[英]Evaluating a postfix expression using expression tree in C
I can't seem to get this program to work, it is a doubly linked list representation of expression tree. 我似乎无法使该程序正常工作,它是表达式树的双向链接列表表示形式。 After creating the tree I need to evaluate the result but I can't seem to figure out how.
创建树后,我需要评估结果,但是我似乎不知道如何做。
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
typedef struct node
{
char item;
struct node * left;
struct node * right;
}*Btree;
Btree root;
void operandFunc(char);
void operatorFunc(char);
void push(Btree);
Btree pop();
void infix(Btree);
void postfix(Btree);
void prefix(Btree);
int solve(Btree);
int calculate(char,int,int);
int isOperand(char);
char expression[25];
Btree stack[25];
int stackPtr = -1;
int main()
{
int count = 0;
printf("Please enter a postfix expression\n");
while((expression[count++]=getchar())!='\n');
expression[--count] = '\0';
//puts(expression);
for(count = 0;expression[count]!='\0';count++)
{
switch(expression[count])
{
case '+':
case '-':
case '*':
case '/':
case '^':
case '%':
case '$':
operatorFunc(expression[count]);
break;
default:
operandFunc(expression[count]);
}
}
if(stackPtr != 0)
{
printf("Incomplete / Incorrect postfix expression given!\n");
}
else
{
printf("\n\nThe result = %d",solve(stack[stackPtr])+'0');
printf("\n\n");
return 0;
}
}
void prefix(Btree root)
{
Btree temp = root;
if(temp)
{
printf("%c ",temp->item);
prefix(temp->left);
prefix(temp->right);
}
}
void infix(Btree root)
{
Btree temp = root;
if(temp != NULL)
{
infix(temp->left);
printf("%c ",temp->item);
infix(temp->right);
}
}
void postfix(Btree root)
{
Btree temp = root;
if(temp)
{
postfix(temp->left);
postfix(temp->right);
printf("%c ",temp->item);
}
}
void push(Btree root)
{
stack[++stackPtr] = root;
}
Btree pop()
{
return (stack[stackPtr--]);
}
void operandFunc(char var)
{
Btree root = (Btree)malloc(sizeof(struct node));
root->item= var;
root->left= NULL;
root->right= NULL;
push(root);
}
void operatorFunc(char var)
{
Btree root = (Btree)malloc(sizeof(struct node));
root->item = var;
root->right = pop();
root->left = pop();
push(root);
}
int solve(Btree root)
{
Btree temp = root;
char num1,num2;
char operator;
int result;
if(temp)
{
Btree LEFTP = temp->left;
Btree RIGHTP = temp->right;
if(LEFTP)
{
if(isOperand(LEFTP->item))
{
num1 = LEFTP->item;
}
else
{
num1 = solve(LEFTP);
}
}
if(RIGHTP)
{
if(isOperand(RIGHTP->item))
{
num2 = RIGHTP->item;
}
else
{
num2 = solve(RIGHTP);
}
}
operator = temp->item;
printf("Test 1 = %c, num1 = %c, num2 = %c\n",operator,num1,num2);
result = calculate(operator,num1-'0',num2-'0');
printf("Test Result = %d\n",result);
temp->item = (result+'0');
printf("Root Item = %c and %d\n",temp->item,temp->item);
return result;
}
return NULL;
}
int calculate(char operator,int op1,int op2)
{
printf("Operator = %c , num1 = %d, num2 = %d\n",operator,op1,op2);
switch(operator)
{
case '+': return(op1+op2);
break;
case '-': return(op1-op2);
break;
case '*': return(op1*op2);
break;
case '/': return(op1/op2);
break;
case '%': return(op1%op2);
break;
case '$': return pow(op1,op2);
break;
default: printf("\n illegal operation.");
exit;
}
}
int isOperand(char var)
{
switch(var)
{
case '+':
case '-':
case '*':
case '/':
case '$':
case '%':
return 0;
default:
return 1;
}
}
I'm having trouble converting and returning the characters as integers. 我在转换和返回整数字符时遇到麻烦。
UPDATE 1: I was able to make it solve single digit number inputs to recieve a multi digit result. 更新1:我能够使它解决一位数字输入,以获得多位数的结果。 I'm still working on a new data structure to compute multi digit numbers.
我仍在研究一种新的数据结构以计算多位数。 Here's the updated code below.
这是下面的更新代码。
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
typedef struct node
{
char item;
struct node * left;
struct node * right;
}*Btree;
Btree root;
void operandFunc(char);
void operatorFunc(char);
void push(Btree);
Btree pop();
void infix(Btree);
void postfix(Btree);
void prefix(Btree);
int solve(Btree);
int calculate(char,int,int);
int isOperand(char);
char expression[25];
Btree stack[25];
int stackPtr = -1;
int main()
{
int count = 0;
printf("Please enter a postfix expression\n");
while((expression[count++]=getchar())!='\n');
expression[--count] = '\0';
//puts(expression);
for(count = 0;expression[count]!='\0';count++)
{
switch(expression[count])
{
case '+':
case '-':
case '*':
case '/':
case '^':
case '%':
case '$':
operatorFunc(expression[count]);
break;
default:
operandFunc(expression[count]);
}
}
if(stackPtr != 0)
{
printf("Incomplete / Incorrect postfix expression given!\n");
}
else
{
printf("\n\nThe result = %d",solve(stack[stackPtr])-'0');
printf("\n\n");
return 0;
}
}
void prefix(Btree root)
{
Btree temp = root;
if(temp)
{
printf("%c ",temp->item);
prefix(temp->left);
prefix(temp->right);
}
}
void infix(Btree root)
{
Btree temp = root;
if(temp != NULL)
{
infix(temp->left);
printf("%c ",temp->item);
infix(temp->right);
}
}
void postfix(Btree root)
{
Btree temp = root;
if(temp)
{
postfix(temp->left);
postfix(temp->right);
printf("%c ",temp->item);
}
}
void push(Btree root)
{
stack[++stackPtr] = root;
}
Btree pop()
{
return (stack[stackPtr--]);
}
void operandFunc(char var)
{
Btree root = (Btree)malloc(sizeof(struct node));
root->item= var;
root->left= NULL;
root->right= NULL;
push(root);
}
void operatorFunc(char var)
{
Btree root = (Btree)malloc(sizeof(struct node));
root->item = var;
root->right = pop();
root->left = pop();
push(root);
}
int solve(Btree root)
{
Btree temp = root;
char num1,num2;
char operator;
int result;
if(temp)
{
Btree LEFTP = temp->left;
Btree RIGHTP = temp->right;
if(LEFTP)
{
if(isOperand(LEFTP->item))
{
num1 = LEFTP->item;
}
else
{
num1 = solve(LEFTP);
}
}
if(RIGHTP)
{
if(isOperand(RIGHTP->item))
{
num2 = RIGHTP->item;
}
else
{
num2 = solve(RIGHTP);
}
}
operator = temp->item;
printf("Test 1 = %c, num1 = %c, num2 = %c\n",operator,num1,num2);
result = calculate(operator,num1-'0',num2-'0');
printf("Test Result = %d\n",result);
temp->item = (result+'0');
printf("Root Item = %c and %d\n",temp->item,temp->item);
return root->item;
}
return NULL;
}
int calculate(char operator,int op1,int op2)
{
printf("Operator = %c , num1 = %d, num2 = %d\n",operator,op1,op2);
switch(operator)
{
case '+': return(op1+op2);
break;
case '-': return(op1-op2);
break;
case '*': return(op1*op2);
break;
case '/': return(op1/op2);
break;
case '%': return(op1%op2);
break;
case '$': return pow(op1,op2);
break;
default: printf("\n illegal operation.");
exit;
}
}
int isOperand(char var)
{
switch(var)
{
case '+':
case '-':
case '*':
case '/':
case '$':
case '%':
return 0;
default:
return 1;
}
}
In operandFunc(expression[count]);
在
operandFunc(expression[count]);
you are only processing one character. 您只处理一个字符。 That means you cannot work with multi-character operands like
10
or 123
. 这意味着您不能使用
10
或123
类的多字符操作数。 If these occur, you push each digit separately. 如果发生这种情况,请分别按每个数字。 So your language is limited to single digit numbers (OK; your decission).
因此,您的语言仅限于一位数字(确定;您的决定)。
In solve
you say printf("Root Item = %c and %d\\n",temp->item,temp->item);
在
solve
您说printf("Root Item = %c and %d\\n",temp->item,temp->item);
. 。 Here, the second argument must be converted to an int:
temp->item-'0'
. 在这里,第二个参数必须转换为int:
temp->item-'0'
。 You have to do that whenever you use %d
in the printf format. 每当您以printf格式使用
%d
时,都必须这样做。
The rest of your code looks fine. 您的其余代码看起来不错。 Maybe set a higher warning level when compiling to find more errors?
也许在发现更多错误时设置了更高的警告级别?
EDIT/ADDITION: How to handle multi-digit numbers? 编辑/添加:如何处理多位数字?
The following snippet handles multi-digit numbers. 以下代码段处理多位数的数字。 You must adapt your struct to make a difference between chars and ints and change operandFunc to handle these numbers:
您必须调整结构以使char和ints之间有所区别,并更改operandFunc以处理以下数字:
while((c=getchar())!='\n')
{
switch(c)
{
case '+':
case '-':
case '*':
case '/':
case '^':
case '%':
case '$':
operatorFunc(c);
break;
default: // assume digit(s)
num= c-'0';
while ((c=getchar())!='\n' && isdigit(c)) num= num*10+c-'0';
operandFunc(num);
ungetc(c,stdin);
}
}
We can evaluate the postfix expression using the binary tree by keeping in mind the two conditions 我们可以通过记住两个条件来使用二叉树评估后缀表达式
if eval(root) is an operator we use recursion, eval(root->llink) + eval(root->rlink) else we return root->info - '0' 如果eval(root)是运算符,则使用递归,eval(root-> llink)+ eval(root-> rlink)否则,我们返回root-> info-'0'
Function for evaluation 评估功能
float evaluate(NODE root)
{
float num;
switch(root->info)
{
case '+' : return eval(root->llink) + eval(root->rlink);
case '-' : return eval(root->llink) - eval(root->rlink);
case '/' : return eval(root->llink) / eval(root->rlink);
case '*' : return eval(root->llink) * eval(root->rlink);
case $ :
case ^ : return pow( eval(root->llink) ,eval(root->rlink));
default : if(isalpha(root->info))
{
printf("%c" = root->info);
scanf("%f",&num);
return num;
}
else
return root->info - '0';
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.