Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions DSA_Project1/calc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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);

Expand Down
Binary file modified DSA_Project1/calculator
Binary file not shown.
158 changes: 105 additions & 53 deletions DSA_Project1/eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,36 @@
#include <math.h>
#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;
Expand All @@ -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) {
Expand All @@ -118,24 +146,36 @@ 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 {
i++;
}
}

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;

Expand Down Expand Up @@ -166,18 +206,30 @@ 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 {
i--;
}
}

return popNum(&values);
return popNode(&nodes);
}

double evalPrefix(const char *expr) {
Node *tree = buildTreeFromPrefix(expr);
double result = evaluateTree(tree);
freeTree(tree);
return result;
}
4 changes: 2 additions & 2 deletions DSA_Project1/gui.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down
8 changes: 4 additions & 4 deletions DSA_Project1/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
8 changes: 0 additions & 8 deletions DSA_Project1/stack.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,6 @@
#include <stdlib.h>
#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;
}
Expand Down
7 changes: 6 additions & 1 deletion DSA_Project1/test.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
((11-1) * 5) + 2
10+1
10+1
15*2+8-4
(20-5)/(3+2)
100*2-50+25
7+8*2-3/3
(6+4)*(9-3)/2
11 changes: 11 additions & 0 deletions DSA_Project1/test_cases.txt
Original file line number Diff line number Diff line change
@@ -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