Popular Posts

Showing posts with label Program for postorder traversal. in c. Show all posts
Showing posts with label Program for postorder traversal. in c. Show all 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;
}
}