表达式树 (二叉树的应用)
#include <iostream> #include <string> #include <cstring> #define MAX 1005 using namespace std; /************************************************************************************************************* 表达式树:将一个四则运算表达式(含括号)转化成二叉树并计算结果 创建树(递归): 1,找到“最后运算”的运算符(一定为树的根),然后递归创建 2,利用 p == 0 时找到最右出现的 + - 和 * / 运算符,分别用 c1 c2保存位置 p != 0时该操作符一定在括号内,且括号一定不是最后计算,只有 p == 0才考虑当前字符 3,当 c1 < 0时,说明没有 + - 操作符出现在最右,则需考虑 * /运算符。(c1 = c2) 若 c2 也小于 0,说明整个算式最右无 + - * /,即整个算式都在一个大括号内 去掉括号递归调用即可 build_tree(x+1,y-1); 4,递归创建左右子树即可 5,计算表达式的结果,递归遍历树即可,碰到叶子结点即非操作符结点 return 即可; Input: a+b a+b*(f-a)-d/b (a+b*c) OutPut: 3 9 7 PS:这里写的是一个一般化的程序,如果输入数字,将字母改成数字即可 *************************************************************************************************************/ string s; int nc; //结点编号 int lch[MAX],rch[MAX]; //左右孩子结点编号 char op[MAX]; //结点的操作字符 int ans = 0; //计算结果 int build_tree(int x,int y){ int c1 = -1,c2 = -1,p = 0; int u; //结点编号 if(y-x == 1){ u = ++nc; lch[u] = rch[u] = 0; op[u] = s[x]; return u; } for(int i = x;i < y;i ++){ if(s[i] == '(') p++; if(s[i] == ')') p--; if(!p && (s[i] == '+' || s[i] == '-')) c1 = i; if(!p && (s[i] == '*' || s[i] == '/')) c2 = i; } if(c1 < 0 && c2 < 0) //找不到最后出现的四则运算符号,即整个算式被大括号括着 return build_tree(x+1,y-1); if(c1 < 0) //找不到 + || - 运算,就用 * || / 运算 c1 = c2; u = ++nc; lch[u] = build_tree(x,c1); rch[u] = build_tree(c1+1,y); op[u] = s[c1]; return u; } int dfs(int id){ if(isalpha(op[id])) return (int)(op[id]-'a' + 1); if(op[id] == '+') return dfs(lch[id]) + dfs(rch[id]); if(op[id] == '-') return dfs(lch[id]) - dfs(rch[id]); if(op[id] == '*') return dfs(lch[id]) * dfs(rch[id]); if(op[id] == '/') return dfs(lch[id]) / dfs(rch[id]); } int main() { while(cin>>s){ nc = 0; //每次重置结点编号从0开始 int len = s.size(); build_tree(0,len); /*for(int i = 1;i <= nc;i ++) //可利用输出查看树的构建情况,包括根节点,左右孩子结点 cout<<"op: "<<op[i]<<" lch: "<<lch[i]<<" rch: "<<rch[i]<<endl;*/ ans = dfs(1); cout<<ans<<endl; } return 0; }