111 lines
3.3 KiB
C
111 lines
3.3 KiB
C
#include "my_str.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
|
|
/*
|
|
Use this command to run
|
|
|
|
gcc -DMY_STR_BUILD_DLL -shared my_str.c -o my_str.dll -Wl,--out-implib,libmy_str.a
|
|
|
|
*/
|
|
|
|
|
|
// Define maximum capacity for stacks
|
|
#define MAX 100
|
|
|
|
// Operand stack to store numbers
|
|
static double numStack[MAX];
|
|
static int numTop = -1;
|
|
|
|
// Operator stack to store characters (+, -, *, /, ()
|
|
static char opStack[MAX];
|
|
static int opTop = -1;
|
|
|
|
// Stack operations
|
|
static void pushNum(double val) { numStack[++numTop] = val; }
|
|
static double popNum() { return numStack[numTop--]; }
|
|
static void pushOp(char op) { opStack[++opTop] = op; }
|
|
static char popOp() { return opStack[opTop--]; }
|
|
static char peekOp() { return opStack[opTop]; }
|
|
|
|
// Returns priority of operators: Higher value means higher precedence
|
|
static int priority(char op) {
|
|
if (op == '+' || op == '-') return 1;
|
|
if (op == '*' || op == '/') return 2;
|
|
return 0; // Parentheses have the lowest priority inside the stack
|
|
}
|
|
|
|
// Performs arithmetic operations
|
|
static double applyOp(double a, double b, char op) {
|
|
switch (op) {
|
|
case '+': return a + b;
|
|
case '-': return a - b;
|
|
case '*': return a * b;
|
|
case '/':
|
|
if (b == 0) {
|
|
printf("Error: Division by zero\n");
|
|
return 0;
|
|
}
|
|
return a / b;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// Main function to evaluate infix expression
|
|
double evaluate(const char* exp) {
|
|
for (int i = 0; exp[i] != '\0'; i++) {
|
|
// 1. Skip whitespace characters
|
|
if (exp[i] == ' ' || exp[i] == '\t') continue;
|
|
|
|
// 2. If the character is a digit, parse the full number (supports multi-digit)
|
|
if (isdigit(exp[i])) {
|
|
double val = 0;
|
|
while (i < strlen(exp) && isdigit(exp[i])) {
|
|
val = (val * 10) + (exp[i] - '0');
|
|
i++;
|
|
}
|
|
pushNum(val);
|
|
i--; // Decrement index because the loop increments it
|
|
}
|
|
// 3. If left parenthesis, push it to the operator stack
|
|
else if (exp[i] == '(') {
|
|
pushOp(exp[i]);
|
|
}
|
|
// 4. If right parenthesis, solve the entire bracket
|
|
else if (exp[i] == ')') {
|
|
while (opTop != -1 && peekOp() != '(') {
|
|
double val2 = popNum();
|
|
double val1 = popNum();
|
|
char op = popOp();
|
|
pushNum(applyOp(val1, val2, op));
|
|
}
|
|
if (opTop != -1) popOp(); // Remove '(' from stack
|
|
}
|
|
// 5. If character is an operator
|
|
else {
|
|
// While the top of the stack has same or higher precedence, calculate
|
|
while (opTop != -1 && priority(peekOp()) >= priority(exp[i])) {
|
|
double val2 = popNum();
|
|
double val1 = popNum();
|
|
char op = popOp();
|
|
pushNum(applyOp(val1, val2, op));
|
|
}
|
|
// Push current operator to stack
|
|
pushOp(exp[i]);
|
|
}
|
|
}
|
|
|
|
// 6. Entire expression parsed, calculate remaining operations in stack
|
|
while (opTop != -1) {
|
|
double val2 = popNum();
|
|
double val1 = popNum();
|
|
char op = popOp();
|
|
pushNum(applyOp(val1, val2, op));
|
|
}
|
|
|
|
// The final result is the only element left in the operand stack
|
|
return popNum();
|
|
}
|