Popular Posts

Monday, August 8, 2011


Program for expression solving using postorder traversing and Tree. (can detect number of variable length, not single upto 128 char lenght.) in c.
#include<stdio.h>
#include<stdlib.h>

#define MINUS 45
#define PLUS         43
#define MUL 42
#define DIV 47
#define MOD 37
#define EXPO         94
#define MAX 128

struct TREE {
struct TREE * left;
double opnd;
char oprt;
struct TREE * right;
};
typedef struct TREE tree;

char stack[MAX]; // stack.
char out[MAX / 2]; // holds the output stack.
char numchar[MAX / 2]; // char array used to hold the chars to convert in to number.
int backTrack = 0; // Keep track of the maching brackets.
int addressStack[MAX / 2]; // Used for the convertion from posrfix to expression tree.
int atop = -1; // Address stack top.
int numchari = 0; // Keep track of number of characters in the char array.
int top = -1; // Top of the stack.
double num = 0; // Holds the temparary output of number converted form char array.

char popFromStack();
int priority(char);
int isdig(char);
int isoprat(char);
double evaluate(tree *);
void pushOnStack(char);
void pushAddressStack(tree *);
void expressionTree(tree *);
void reset();
tree * popAddressStack();
tree * postorder();
tree * newNode(double, char);
tree * pushTreeNode(tree *, double, char);

void main() {
tree *root = postorder();
if (root) {
//Postorder Success.
expressionTree(root);
double val = evaluate((tree *) addressStack[atop]);
printf("%lf\n", val);
} else {
//Postorder Failed.
printf("Somethig went worng. :( Sorry.!\n");
}
}

tree * postorder() {
tree *root = NULL;
char ch;
int8_t i = 0;
int8_t nflag = 1; // Toggle in -/+ values.
char *exp = "5+3+   (3+4)";//"(-((-2*4)+-7))/((5-7)+4)"; //"2*3/(2-1)+5*(4-1)";
while (ch = exp[i++]) {
if (ch == ' ' || ch == '\t') {
continue;
}
if (ch == MINUS || ch == PLUS || ch == MUL || ch == DIV || ch == MOD || ch == EXPO || ch == '(' || ch == ')') {
//In case of operators.
if (ch == '(') {
backTrack++;
pushOnStack(ch);
} else if (ch == ')') {
backTrack--;
while (1) {
ch = popFromStack();
if (ch == '(') {
break;
}
root = pushTreeNode(root, 0, ch);
}
} else {
// Now its operator. the four conditions here.
// Never try to combine these four case in while. everything is dependent.
while (1) {
//i) If stack is empty, push operator on stack.
if (top == -1) {
pushOnStack(ch);
break;
}
//ii) If the top of the stack is opening parenthesis, push operator on stack.
if (stack[top] == '(') {
pushOnStack(ch);
break;
}
//iii) If it has higher priority than the top of stack, push operator on stack.
if (priority(ch) > priority(stack[top])) {
pushOnStack(ch);
break;
} //iv) Else pop the operator from the stack and output it, repeat step 4.
else {
char ch2 = popFromStack();
root = pushTreeNode(root, 0, ch2);
continue;
}
}
}
} else {
//In case of operends..
while (1) {
if (ch >= '0' && ch <= '9' || ch == '.') {
numchar[numchari++] = ch;
ch = exp[i++];
} else {
break;
}
}
num = atof(numchar);
i--;
numchari = 0;
reset(numchar);
root = pushTreeNode(root, num*nflag, 0);
num = 0;
//outputit(ch);
}
}
while (1) {
char ch = popFromStack();
root = pushTreeNode(root, 0, ch);
if (top == -1) {
break;
}
}
if (backTrack) {
printf("No matching bracket(s). Check your expression.\n");
return NULL;
}
//pars(root);
return root;
}

int isdig(char ch) {
if (ch >= '0' || ch <= '9') {
return 1;
} else {
return 0;
}
}

int isoprat(char ch) {
if (ch == MINUS || ch == PLUS || ch == MUL || ch == DIV || ch == MOD || ch == EXPO) {
return 1;
} else {
return 0;
}
}

void expressionTree(tree * node) {
if (node == NULL) {
return;
} else {
tree *right = node->right;
int a = node->opnd;
int b = node->oprt;
if (node->oprt == 0) {
node->left = NULL;
node->right = NULL;
pushAddressStack(node);
expressionTree(right);
} else {
node->right = popAddressStack();
node->left = popAddressStack();
pushAddressStack(node);
expressionTree(right);
}
}
}

double evaluate(tree *node) {
if (node == NULL) {
printf(" %lf ", node->opnd);
return;
}
if (node->opnd == 0 && node->oprt != 0) {
double a, b, c;
a = evaluate(node->left);
b = evaluate(node->right);
free(node);
switch (node->oprt) {
case MINUS: c = a - b;
break;
case PLUS: c = a + b;
break;
case MUL: c = a * b;
break;
case DIV: c = a / b;
break;
}
return c;
} else {
return node->opnd;
}
}

tree * popAddressStack() {
if (atop == -1) {
printf("Address stack empty.\n");
exit(EXIT_FAILURE);
}
tree *node = (tree *) addressStack[atop];
atop--;
return node;
}

void pushAddressStack(tree *node) {
if (atop >= MAX) {
printf("Overflow.\n");
exit(EXIT_FAILURE);
}
atop++;
addressStack[atop] = (int) node;
}

tree * newNode(double val, char ch) {
tree * node = malloc(sizeof (tree));
if (node) {
node->left = NULL;
node->right = NULL;
node->opnd = val;
node->oprt = ch;
return node;
} else {
exit(0);
}
}

tree * pushTreeNode(tree *node, double val, char ch) {
if (node == NULL) {
node = newNode(val, ch);
return node;
} else {
node->right = pushTreeNode(node->right, val, ch);
return node;
}
return node;
}

void reset(char *numchar) {
int j = 0;
for (j = 0; j < MAX; j++) {
numchar[j] = 0;
}
}

int priority(char c) {
if (c == '^')
return 3; /*Exponential operator*/
if (c == '*' || c == '/' || c == '%')
return 2;
else if (c == '+' || c == '-')
return 1;
else
return 0;
}

void pushOnStack(char ch) {
top++;
if (top >= MAX) {
exit(EXIT_FAILURE);
} else {
stack[top] = ch;
int a = 0;
}
}

char popFromStack() {
if (top == -1) {
printf("STACK is already empry.\n");
printf("May be Invalid expression.\n");
exit(EXIT_FAILURE);
} else {
char ch = stack[top];
top--;
return ch;
}
}