核心算法:
mid=FormatMid(mid); //格式化中缀表达式JudgeLegalMid(mid); //判断中缀表达式的合法性MidToPost mtp(mid);mtp.ToPost(post); //中缀表达式转后缀表达式cout <<"结果:" <<
具体过程——
第一步:格式化中缀表达式
这一步的目的是为了解决“-”的歧义问题:有时候“-”是一元运算符,有时候“-”是二元运算符。可以用一种巧妙的方案解决歧义——在一元运算符的“-”前面添上0。这样,此后就可以把+-*/统一当做二元运算符处理。
具体代码:(放在FormatMid.h文件中)
#include#include #include using namespace std;string FormatMid(string mid){ for (int i=0;i
第二步:判断中缀表达式的合法性
这一步也是为了程序的鲁棒性,具体代码如下:(放在JudgeLegalMid.h文件中)
#include#include #include #include using namespace std;void illegal(){ cout <<"表达式不合法!" < 0 && isdigit(c[j])) j--; while (k
第三步:中缀表达式转后缀表达式
这一步是比较经典的栈处理,具体代码如下:(放在MidToPost.h文件中,封装成了类)
#ifndef MIDTOPOST_H____#define MIDTOPOST_H____#include#include #include #include #include #include using namespace std;string cts(char cc){ stringstream stream; stream << cc; return stream.str();}class MidToPost{ private: string c; stack s; int yxj(char ope); //返回一个运算符的优先级 public: MidToPost(const string cc); //构造函数 void ToPost(vector & res); //转为后缀表达式 string readnum(int p); };int MidToPost::yxj(char ope){ if (ope=='*' || ope=='/') return 1; if (ope=='+' || ope=='-') return 0; if (ope=='@' || ope=='(') return -1;}string MidToPost::readnum(int p){ string s=""; while (isdigit(c[p]) || c[p]=='.') { s+=cts(c[p]); p++; } return s;}MidToPost::MidToPost(const string cc) { c=cc; while (!s.empty()) s.pop(); s.push(string("@"));}void MidToPost::ToPost(vector & res){ res.clear(); int now=0; int l=c.length(); for (int i=0;i =k2) { res.push_back(s.top()); s.pop(); k1=yxj(s.top()[0]); k2=yxj(c[i]); } s.push(cts(c[i])); } } while (s.top()[0]!='@') { res.push_back(s.top()); s.pop(); }}#endif
第四步:计算后缀表达式的值
同样是经典的栈处理,对于除数为0的情况由于C++自带inf所以就没有特判。代码如下:(放在CalcPost.h文件中)
#include#include #include #include #include #include using namespace std;stack s;double Calc(vector & c){ while (!s.empty()) s.pop(); int l=c.size(); for (int i=0;i >tmp; s.push(tmp); } else { double res2=s.top(); s.pop(); double res1=s.top(); s.pop(); switch(c[i][0]) { case '+':res1+=res2;break; case '-':res1-=res2;break; case '*':res1*=res2;break; case '/':res1/=res2;break; } s.push(res1); } } return s.top();}
主程序:
#include"MidToPost.h"#include"CalcPost.h"#include"JudgeLegalMid.h"#include"FormatMid.h"#include#include #include #include using namespace std;const int maxn=2000;string mid;vector post;int main(){ cout <<"请输入中缀表达式(实数加减乘除括号运算):"; while (cin >>mid) { mid=FormatMid(mid); cout <<"等价转换后的中缀表达式:" < <
运行结果: