中缀 后缀表达式求值

来源:互联网 发布:js广告 编辑:程序博客网 时间:2024/05/21 07:12

一.中缀转后缀

1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:例如加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈。
6.最终将栈中的元素依次出栈,输出。

二.由后缀表达式得到表达式树


三.对表达式树的根节点调用cal()虚函数就能算出表达式的值


代码

#include<iostream>#include<string>#include<map>#include<stack>using namespace std;map<char, int> m{{'*', 3}, {'/', 3},{'+', 4}, {'-', 4},{'(', 99}};//定义优先级 class node{public:virtual double cal() const = 0;virtual ~node () {}}; class numnode : public node{public:numnode(double d):number(d){}virtual double cal() const;private:double number;};class binarynode : public node{protected:node* _left;node* _right;public:binarynode(node* left, node* right):_left(left),_right(right){}~binarynode();};class addnode : public binarynode{public:addnode(node* left, node* right):binarynode(left, right){};virtual double cal() const;};class mutinode : public binarynode{public:mutinode(node* left, node* right):binarynode(left, right){};virtual double cal() const;};inline double numnode::cal() const{return number;}binarynode::~binarynode() {delete _left;delete _right;}double addnode::cal() const{return _left->cal() + _right->cal();}double mutinode::cal() const{return _left->cal() * _right->cal();}string suffix(const string& str) //得到后缀表达式{stack<char> sta;string ret;for(int i=0; i<str.size(); i++){if( str[i]=='.' || (str[i]>='0' && str[i]<='9') ){ret += str[i];}else{if(ret.back() != ' ')ret += " " ;if( sta.empty() || str[i]=='(' )sta.push(str[i]);else if(str[i] == ')'){while(sta.top()!='('){ret.push_back(sta.top());ret.push_back(' '); sta.pop();}sta.pop();}else {while( !sta.empty() && m[str[i]]>=m[sta.top()] ){ret = ret + sta.top()+" ";sta.pop();}sta.push(str[i]);}}//cout<<i+1<<" "<<ret<<endl;}ret += " ";//确保每个数后边都有个空格 while(!sta.empty()){ret = ret + sta.top()+" ";sta.pop();}return ret;}node* suffix_tree(const string& str)//生成后缀表达式树{stack<node*> sta;string temp;node* left;node* right;for(int i=0; i<str.size(); i++){//cout<<i<<endl;if( str[i]=='.' || (str[i]>='0' && str[i]<='9') ){temp += str[i];//cout<<"temp"<<temp<<endl;}else if(str[i]==' ' && str[i-1]>='0' && str[i-1]<='9' ){double d = stod(temp);node *pnode = new numnode(d);sta.push(pnode);temp = "";}else if(str[i]==' ')continue;else switch(str[i]){case '+':right = sta.top();sta.pop();left = sta.top();sta.pop();sta.push(new addnode(left,right));break;case '*':right = sta.top();sta.pop();left = sta.top();sta.pop();sta.push(new mutinode(left,right));break;}}return sta.top();}int main(){string temp = "11.0+22*33+(44.0*55+66)*77";cout<<"11.0+22*33+(44.0*55+66)*77的后缀表达式:";//11.0 22 33 * + 44.0 55 * 66 + 77 * +string sur = suffix(temp);cout<<sur<<endl;node* root = suffix_tree(sur);double x = root->cal();cout << x << endl;//192159delete root;}


还有一种不面向对象的。

一.中缀转后缀

二.由后缀直接得到结果

#include<iostream>#include<string>#include<map>#include<stack>using namespace std;map<char, int> m{{'*', 3}, {'/', 3},{'+', 4}, {'-', 4},{'(', 99}};string suffix(const string& str){stack<char> sta;string ret;for(int i=0; i<str.size(); i++){if(str[i]>='0' && str[i]<='9'){ret += str[i];}else{if(ret.back() != ' ')ret += " " ;if( sta.empty() || str[i]=='(' )sta.push(str[i]);else if(str[i] == ')'){while(sta.top()!='('){ret = ret + sta.top()+" ";sta.pop();}sta.pop();}else {while( !sta.empty() && m[str[i]]>=m[sta.top()] ){ret = ret + sta.top()+" ";sta.pop();}sta.push(str[i]);}}//cout<<i+1<<" "<<ret<<endl;}ret += " ";//确保每个数后边都有个空格 while(!sta.empty()){ret = ret + sta.top()+" ";sta.pop();}return ret;}int cal(const string &str){stack<int> sta;string temp;int left = 0;int right = 0;for(int i=0; i<str.size(); i++){//cout<<i<<endl;if(str[i]>='0' && str[i]<='9'){temp += str[i];//cout<<"temp"<<temp<<endl;}else if(str[i]==' ' && str[i-1]>='0' && str[i-1]<='9' ){sta.push(stoi(temp));temp = "";}else if(str[i]==' ')continue;else switch(str[i]){case '+':right = sta.top();//cout<<"right"<<right<<endl;sta.pop();left = sta.top();//cout<<"left"<<left<<endl;sta.pop();sta.push(left+right);//cout<<"jia"<<sta.top() <<endl;break;case '*':right = sta.top();//cout<<"right"<<right<<endl;sta.pop();left = sta.top();//cout<<"left"<<left<<endl;sta.pop();sta.push(left*right);//cout<<"cheng"<<sta.top() <<endl;break;}}return sta.top();}int main(){string temp = "11+22*33+(44*55+66)*77";cout<<"11+22*33+(44*55+66)*77的后缀表达式:";//11 22 33 *+ 44 55 *66 + 77 *+string sur = suffix(temp);cout<<sur<<endl;cout<<"表达式的和:";int sum = cal(sur);cout<<sum<<endl;}

参考:http://www.cnblogs.com/Solstice/archive/2012/07/06/learncpp.html
http://www.relisoft.com/book/lang/poly/3tree.html

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 有急事请假不批怎么办 员工要请假不批怎么办 普法知识竞赛要重新参与怎么办 我被当兵的打怎么办 头发没了一小块怎么办 改革怎么看我该怎么办 笔记本电脑卡死了怎么办关不了机 电脑卡死了怎么办关不了机 火车上别人占座怎么办 火车上遇到占座怎么办 青少年体力差容易疲劳怎么办 四年级的孩子作业拖拉怎么办 四年级孩子不写作业怎么办 四年级孩子不爱写作业怎么办 四年级的孩子写作业慢怎么办 四年级孩子不想写作业怎么办 四年级孩子写作业特别慢怎么办 6岁儿童睡眠少怎么办 四岁儿童睡眠少怎么办 因睡眠不足第二天没有精神怎么办 睡时间久了头疼怎么办 睡不踏实老醒怎么办 运动过后大腿肌肉酸痛怎么办 牛奶喝多了想吐怎么办 运动过度后吐了怎么办 喝酒后反胃想吐怎么办 拔牙后反胃想吐怎么办 健身完恶心想吐怎么办 锻炼后头晕想吐怎么办 高三学生睡眠不好怎么办 狗狗精力太旺盛怎么办 新入职的同事比你厉害怎么办 银子弹鞋开胶了怎么办 我很笨脑子反应慢怎么办 学车脑子不好使怎么办 生完二胎脑子不好使怎么办 羽毛球鞋买小了怎么办 羽毛球鞋买大了怎么办 感觉自己脑子越来越笨了怎么办? 生完孩子后身体素质差怎么办 胃口太好越来越胖怎么办