diff --git a/DSA_Project1/calc.h b/DSA_Project1/calc.h index abd4f33..01f3ba2 100644 --- a/DSA_Project1/calc.h +++ b/DSA_Project1/calc.h @@ -3,11 +3,6 @@ #define EXPR_MAX 100 -typedef struct { - double data[EXPR_MAX]; - int top; -} numstack; - typedef struct { char data[EXPR_MAX]; int top; @@ -24,9 +19,6 @@ typedef struct { int top; } nodestack; -void pushNum(numstack *s, double val); -double popNum(numstack *s); - void pushOp(opstack *s, char op); char popOp(opstack *s); char peekOp(opstack *s); @@ -38,7 +30,14 @@ int precedence(char op); double applyOp(double a, double b, char op); int isOperator(char c); -double eval(const char *expr); +Node* createNode(const char *data); +void infixToPostfix(const char *infix, char *postfix); +Node* buildTreeFromPostfix(const char *expr); +Node* buildTreeFromPrefix(const char *expr); +double evaluateTree(Node *root); +void freeTree(Node *root); + +double eval_Infix(const char *expr); double evalPostfix(const char *expr); double evalPrefix(const char *expr); diff --git a/DSA_Project1/calculator b/DSA_Project1/calculator index 3a331a7..7d1ca7a 100755 Binary files a/DSA_Project1/calculator and b/DSA_Project1/calculator differ diff --git a/DSA_Project1/eval.c b/DSA_Project1/eval.c index a2cd8ab..9c7931a 100644 --- a/DSA_Project1/eval.c +++ b/DSA_Project1/eval.c @@ -5,6 +5,36 @@ #include #include "calc.h" +Node* createNode(const char *data) { + Node *newNode = (Node*)malloc(sizeof(Node)); + strcpy(newNode->data, data); + newNode->left = NULL; + newNode->right = NULL; + return newNode; +} + +void freeTree(Node *root) { + if (root == NULL) return; + freeTree(root->left); + freeTree(root->right); + free(root); +} + +double evaluateTree(Node *root) { + if (root == NULL) return 0; + + // operand is leaf node + if (root->left == NULL && root->right == NULL) { + return atof(root->data); + } + + // recursive evaluation + double leftVal = evaluateTree(root->left); + double rightVal = evaluateTree(root->right); + + return applyOp(leftVal, rightVal, root->data[0]); +} + int precedence(char op) { if (op == '+' || op == '-') return 1; if (op == '*' || op == '/') return 2; @@ -25,79 +55,77 @@ int isOperator(char c) { return (c == '+' || c == '-' || c == '*' || c == '/'); } -double eval(const char *expr) { - numstack values = {.top = -1}; +void infixToPostfix(const char *infix, char *postfix) { opstack ops = {.top = -1}; - int i = 0, len = strlen(expr); + int i = 0, k = 0, len = strlen(infix); while (i < len) { - if (isspace(expr[i])) { + if (isspace(infix[i])) { i++; continue; } - if (expr[i] == '-' && (i == 0 || expr[i - 1] == '(')) {// expr[i] == '-' for case of unary minus - char numStr[20]; - int j = 0; - numStr[j++] = '-'; + if (infix[i] == '-' && (i == 0 || infix[i - 1] == '(')) {// unary minus + postfix[k++] = '-'; i++; - while (i < len && (isdigit(expr[i]) || expr[i] == '.')) - numStr[j++] = expr[i++]; + while (i < len && (isdigit(infix[i]) || infix[i] == '.')) + postfix[k++] = infix[i++]; - numStr[j] = '\0'; - pushNum(&values, atof(numStr)); + postfix[k++] = ' '; continue; } - if (isdigit(expr[i]) || expr[i] == '.') { - char numStr[20]; - int j = 0; - - while (i < len && (isdigit(expr[i]) || expr[i] == '.')) - numStr[j++] = expr[i++]; + if (isdigit(infix[i]) || infix[i] == '.') { + while (i < len && (isdigit(infix[i]) || infix[i] == '.')) + postfix[k++] = infix[i++]; - numStr[j] = '\0'; - pushNum(&values, atof(numStr)); + postfix[k++] = ' '; } - else if (expr[i] == '(') { - pushOp(&ops, expr[i]); + else if (infix[i] == '(') { + pushOp(&ops, infix[i]); i++; } - else if (expr[i] == ')') { + else if (infix[i] == ')') { while (ops.top != -1 && peekOp(&ops) != '(') { - double b = popNum(&values); - double a = popNum(&values); - char op = popOp(&ops); - pushNum(&values, applyOp(a, b, op)); + postfix[k++] = popOp(&ops); + postfix[k++] = ' '; } popOp(&ops); i++; } - else { - while (ops.top != -1 && precedence(peekOp(&ops)) >= precedence(expr[i])) { - double b = popNum(&values); - double a = popNum(&values); - char op = popOp(&ops); - pushNum(&values, applyOp(a, b, op)); + else if (isOperator(infix[i])) { + while (ops.top != -1 && peekOp(&ops) != '(' && precedence(peekOp(&ops)) >= precedence(infix[i])) { + postfix[k++] = popOp(&ops); + postfix[k++] = ' '; } - pushOp(&ops, expr[i]); + pushOp(&ops, infix[i]); + i++; + } + else { i++; } } while (ops.top != -1) { - double b = popNum(&values); - double a = popNum(&values); - char op = popOp(&ops); - pushNum(&values, applyOp(a, b, op)); + postfix[k++] = popOp(&ops); + postfix[k++] = ' '; } - return popNum(&values); + postfix[k] = '\0'; } -double evalPostfix(const char *expr) { - numstack values = {.top = -1}; +double eval_Infix(const char *expr) { + char postfix[EXPR_MAX * 2]; + infixToPostfix(expr, postfix); + Node *tree = buildTreeFromPostfix(postfix); + double result = evaluateTree(tree); + freeTree(tree); + return result; +} + +Node* buildTreeFromPostfix(const char *expr) { + nodestack nodes = {.top = -1}; int i = 0, len = strlen(expr); while (i < len) { @@ -118,12 +146,17 @@ double evalPostfix(const char *expr) { numStr[j++] = expr[i++]; numStr[j] = '\0'; - pushNum(&values, atof(numStr)); + pushNode(&nodes, createNode(numStr)); } else if (isOperator(expr[i])) { - double b = popNum(&values); - double a = popNum(&values); - pushNum(&values, applyOp(a, b, expr[i])); + Node *right = popNode(&nodes); + Node *left = popNode(&nodes); + + char opStr[2] = {expr[i], '\0'}; + Node *opNode = createNode(opStr); + opNode->left = left; + opNode->right = right; + pushNode(&nodes, opNode); i++; } else { @@ -131,11 +164,18 @@ double evalPostfix(const char *expr) { } } - return popNum(&values); + return popNode(&nodes); } -double evalPrefix(const char *expr) { - numstack values = {.top = -1}; +double evalPostfix(const char *expr) { + Node *tree = buildTreeFromPostfix(expr); + double result = evaluateTree(tree); + freeTree(tree); + return result; +} + +Node* buildTreeFromPrefix(const char *expr) { + nodestack nodes = {.top = -1}; int len = strlen(expr); int i = len - 1; @@ -166,12 +206,17 @@ double evalPrefix(const char *expr) { } numStr[j] = '\0'; - pushNum(&values, atof(numStr)); + pushNode(&nodes, createNode(numStr)); } else if (isOperator(expr[i])) { - double a = popNum(&values); - double b = popNum(&values); - pushNum(&values, applyOp(a, b, expr[i])); + Node *left = popNode(&nodes); + Node *right = popNode(&nodes); + + char opStr[2] = {expr[i], '\0'}; + Node *opNode = createNode(opStr); + opNode->left = left; + opNode->right = right; + pushNode(&nodes, opNode); i--; } else { @@ -179,5 +224,12 @@ double evalPrefix(const char *expr) { } } - return popNum(&values); + return popNode(&nodes); +} + +double evalPrefix(const char *expr) { + Node *tree = buildTreeFromPrefix(expr); + double result = evaluateTree(tree); + freeTree(tree); + return result; } diff --git a/DSA_Project1/gui.c b/DSA_Project1/gui.c index 0547606..c49e4e9 100644 --- a/DSA_Project1/gui.c +++ b/DSA_Project1/gui.c @@ -54,7 +54,7 @@ static void on_calculate_clicked(GtkWidget *widget, gpointer data) { result = evalPrefix(expr); break; default: - result = eval(expr); + result = eval_Infix(expr); break; } @@ -113,7 +113,7 @@ static void on_file_open_clicked(GtkWidget *widget, gpointer data) { result = evalPrefix(expr); break; default: - result = eval(expr); + result = eval_Infix(expr); break; } diff --git a/DSA_Project1/main.c b/DSA_Project1/main.c index 5600541..79116ab 100644 --- a/DSA_Project1/main.c +++ b/DSA_Project1/main.c @@ -15,8 +15,8 @@ int main(int argc, char *argv[]) { printf("2. GUI (Graphical User Interface)\n"); printf("Enter choice (1-2): "); - if (scanf("%d", &mode) != 1) { - mode = 1; // Default to CLI + if (scanf("%d", &mode) != 1) { // Defaults to CLI + mode = 1; } getchar(); @@ -91,7 +91,7 @@ int run_cli() { result = evalPrefix(expr); break; default: - result = eval(expr); + result = eval_Infix(expr); break; } printf("%s = %.2f\n", expr, result); @@ -108,7 +108,7 @@ int run_cli() { result = evalPrefix(expr); break; default: - result = eval(expr); + result = eval_Infix(expr); break; } printf("Result: %.2f\n", result); diff --git a/DSA_Project1/stack.c b/DSA_Project1/stack.c index 1d56fd8..a686cb1 100644 --- a/DSA_Project1/stack.c +++ b/DSA_Project1/stack.c @@ -2,14 +2,6 @@ #include #include "calc.h" -void pushNum(numstack *s, double val) { - s->data[++(s->top)] = val; -} - -double popNum(numstack *s) { - return s->data[(s->top)--]; -} - void pushOp(opstack *s, char op) { s->data[++(s->top)] = op; } diff --git a/DSA_Project1/test.txt b/DSA_Project1/test.txt index 75d1bbb..205e24e 100644 --- a/DSA_Project1/test.txt +++ b/DSA_Project1/test.txt @@ -1,2 +1,7 @@ ((11-1) * 5) + 2 -10+1 \ No newline at end of file +10+1 +15*2+8-4 +(20-5)/(3+2) +100*2-50+25 +7+8*2-3/3 +(6+4)*(9-3)/2 \ No newline at end of file diff --git a/DSA_Project1/test_cases.txt b/DSA_Project1/test_cases.txt new file mode 100644 index 0000000..978aaaf --- /dev/null +++ b/DSA_Project1/test_cases.txt @@ -0,0 +1,11 @@ +=== Infix Expressions === +3+5*2 = 13.00 +(10+5)*2-3 = 27.00 + +=== Postfix Expressions === +3 5 2 * + = 13.00 +10 5 + 2 * 3 - = 3 + +=== Prefix Expressions === ++ 3 * 5 2 = 13.00 +- * + 10 5 2 3 = 27.00