题目:
题目要求: 用二叉树来表示表达式,树的每一个节点包括一个运算符和运算数。代数表达式中只包含+,-,*,/,(,)和一位整数且没有错误。按照先括号,再乘除,后加减的规则构造二叉树。如图所示是"1+(2+3)*2-4/5"代数表达式对应二叉树,用对应的二叉树计算表达式的值。
输入格式:
输入一行表达式字符串,括号内只能有一个运算符。
输出格式:
输出表达式的计算结果.如果除数为0,提示divide 0 error!
各个部分
二叉树节点:
typedef struct BiTNode{
char date;
BiTNode *left,*right;
//构造函数
BiTNode()
{date='#';left=right=NULL;}
BiTNode(char dat)
{ date=dat;left=right=NULL; }
BiTNode(char dat,BiTNode *l,BiTNode *r)
{ date=dat;left=l;right=r; }
}BiTNode,*ExpTree;
判断一个字符是不是运算符即最简单表达式的计算
//判断是否是运算符的函数
bool judge(char c)
{
if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')' || c == '#')
return true;
else return false;
}
int operate(int a,char c,int b)
{//不出现/0的情况
int ans;
if(c=='+')
ans=a+b;
else if(c=='-')
ans=a-b;
else if(c=='*')
ans=a*b;
else
ans=a/b;
return ans;
}
构造表达式二叉树:
void InitExpTree(string s,ExpTree &T)
{
stack<ExpTree> EXPT; //暂存二叉树
stack<char> OPTR; //暂存运算符
OPTR.push('#');
int i=0;
while(s[i]!='#'||OPTR.top()!='#')
{
if(s[i]>='0'&&s[i]<='9')
{
T=new BiTNode(s[i]); //创建只有根节点的二叉树
EXPT.push(T); //新树入栈
i++;
}
else if(judge(s[i]))
{
switch(Precede(OPTR.top(),s[i])) //栈顶元素优先级与当前元素优先级比较
{
case '<':
{
OPTR.push(s[i]);
i++;
break;
}
case '>':
{
char theta=OPTR.top();
OPTR.pop();
ExpTree b=EXPT.top();
EXPT.pop();
ExpTree a=EXPT.top();
EXPT.pop();
//theta为根,a为左子树,b为右子树,创建一颗二叉树;
T=new BiTNode(theta,a,b);
//根节点T进EXPT栈
EXPT.push(T);
break;
}
case '=': //()匹配的情况
{
OPTR.pop();
i++;
break;
}
}//switch
}
// else if(s[i]==' ')
// i++;
// i++;//case '>'时不用i++
}//while
}
优先级比较函数:
//优先级比较函数
char Precede(char e,char c)//e是栈顶元素,c是在读元素
{
int int_e,int_c;//将e和c转化为数字进行比较
map<char,int> optr;
optr['+']=1;optr['-']=2;optr['*']=3;optr['/']=4;
optr['(']=5;optr[')']=6;optr['#']=7;
int_e=optr[e];
int_c=optr[c];
if(int_e==1||int_e==2)
{
if(int_c>=3&&int_c<=5) return'<';
else return'>';
}
if(int_e==3||int_e==4)
{
if(int_c==5) return'<';
else return '>';
}
if(int_e==5)
{
if(int_c==6) return '=';
else if(int_c==7) return '#';
else return '<';
}
if(int_e==6)
{
if(int_c==5) return '#';
else return '>';
}
if(int_e==7)
{
if(int_c==7) return '=';
else if(int_c==6) return '#';
else return '<';
}
}
根据二叉树来求值:
//根据二叉表达式来求值
int EvaluateExpTree(ExpTree T)
{
int lvalue=0,rvalue=0;
if(T->left==NULL && T->right==NULL)
return T->date-'0';
else
{
lvalue=EvaluateExpTree(T->left);
rvalue=EvaluateExpTree(T->right);
return operate(lvalue,T->date,rvalue);
}
}
实现代码:
#include<iostream>
#include<vector>
#include<map>
#include<stack>
using namespace std;
typedef struct BiTNode{
char date;
BiTNode *left,*right;
//构造函数
BiTNode()
{date='#';left=right=NULL;}
BiTNode(char dat)
{ date=dat;left=right=NULL; }
BiTNode(char dat,BiTNode *l,BiTNode *r)
{ date=dat;left=l;right=r; }
}BiTNode,*ExpTree;
//判断是否是运算符的函数
bool judge(char c)
{
if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')' || c == '#')
return true;
else return false;
}
int operate(int a,char c,int b)
{//不出现/0的情况
int ans;
if(c=='+')
ans=a+b;
else if(c=='-')
ans=a-b;
else if(c=='*')
ans=a*b;
else
ans=a/b;
return ans;
}
//优先级比较函数
char Precede(char e,char c)//e是栈顶元素,c是在读元素
{
int int_e,int_c;//将e和c转化为数字进行比较
map<char,int> optr;
optr['+']=1;optr['-']=2;optr['*']=3;optr['/']=4;
optr['(']=5;optr[')']=6;optr['#']=7;
int_e=optr[e];
int_c=optr[c];
if(int_e==1||int_e==2)
{
if(int_c>=3&&int_c<=5) return'<';
else return'>';
}
if(int_e==3||int_e==4)
{
if(int_c==5) return'<';
else return '>';
}
if(int_e==5)
{
if(int_c==6) return '=';
else if(int_c==7) return '#';
else return '<';
}
if(int_e==6)
{
if(int_c==5) return '#';
else return '>';
}
if(int_e==7)
{
if(int_c==7) return '=';
else if(int_c==6) return '#';
else return '<';
}
}
void InitExpTree(string s,ExpTree &T)
{
stack<ExpTree> EXPT; //暂存二叉树
stack<char> OPTR; //暂存运算符
OPTR.push('#');
int i=0;
while(s[i]!='#'||OPTR.top()!='#')
{
if(s[i]>='0'&&s[i]<='9')
{
T=new BiTNode(s[i]); //创建只有根节点的二叉树
EXPT.push(T); //新树入栈
i++;
}
else if(judge(s[i]))
{
switch(Precede(OPTR.top(),s[i])) //栈顶元素优先级与当前元素优先级比较
{
case '<':
{
OPTR.push(s[i]);
i++;
break;
}
case '>':
{
char theta=OPTR.top();
OPTR.pop();
ExpTree b=EXPT.top();
EXPT.pop();
ExpTree a=EXPT.top();
EXPT.pop();
//theta为根,a为左子树,b为右子树,创建一颗二叉树;
T=new BiTNode(theta,a,b);
//根节点T进EXPT栈
EXPT.push(T);
break;
}
case '=': //()匹配的情况
{
OPTR.pop();
i++;
break;
}
}//switch
}
// else if(s[i]==' ')
// i++;
// i++;//case '>'时不用i++
}//while
}
//根据二叉表达式来求值
int EvaluateExpTree(ExpTree T)
{
int lvalue=0,rvalue=0;
if(T->left==NULL && T->right==NULL)
return T->date-'0';
else
{
lvalue=EvaluateExpTree(T->left);
rvalue=EvaluateExpTree(T->right);
return operate(lvalue,T->date,rvalue);
}
}
int main()
{
string s;
cin>>s;
ExpTree root;
InitExpTree(s,root);
int ans=EvaluateExpTree(root);
cout<<"value:"<<ans;
}