单单数据结构上,不考虑具体实现来说,这个算法是这样的:
从左到右扫描每一个字符。
1.遇到数字直接输出。
2.遇到'(',直接压栈。
3.遇到')',弹出栈元素直到遇到左括号(左括号也弹出)。
4.扫描到其他运算符:
(1)当前字符优先级>栈顶字符优先级,直接入栈。
(2)当前字符优先级<=栈顶字符优先级,栈一直pop到栈底或者遇到左括号(左括号不弹出),然后当前字符入栈。
5.扫描到头栈内仍有元素,栈操作依次吐到空即可。
另,操作符优先级(数越小优先级越高)
团长 2 ^
营长 3 * / %
排长 4 + -
( ) 不参与运算符优先级比较,如上述方法特殊处理。为了程序正常运行,可以把左括号设成最低优先级。
自己测试了几个用例,都通过了。
语言是C++。
它用到的数据结构是:一个存放运算符的栈,名字是Sop,和一个存放后缀表达式的vector,名字是res。
它的C++具体规则是:
先设置好每个运算符的优先级。
从左到右依次遍历每一个字符。
1.遇到数字,直接放到push_back到res(也就是存放最终结果的vector)里面。
2.遇到 '(',直接压到Sop(算法用到的栈)里面。
3.遇到 ')',就把Sop的栈顶元素依次push_back到res里面,直到遇到左括号(左括号也弹出),同时注意,不要把左括号和右括号输出到res里。
4.遇到其他的运算符,
(1)如果Sop是空的,直接入栈。
(2)比较Sop的栈顶运算符和当前运算符的优先级:
如果当前运算符str[i]的运算符 优先于 栈顶运算符Sop.top(),那么str[i]入栈。
如果不是,就一直弹出栈顶的运算符到vector里面,直到弹到栈空或者弹到左括号(左括号不弹出),然后压入当前运算符。
5.当for遍历完所有的字符之后,Sop这个栈里还有运算符,那么依次弹出栈顶元素直到栈空。
这个小demo是操作数只能个位的操作数。
然后是计算函数,后缀表达式的计算很简单,就不详细说了。
贴一下代码。2020.4.19,更新了代码。
#include <bits/stdc++.h>
using namespace std;
bool isNum(char a){
return (a<='9'&&a>='0');
}
char* NifixToSuffix(string str){
string res;
stack<char> Sop;
int k=0;
map<char,int> priority;
priority['(']=1;
priority['^']=2;
priority['/']=priority['*']=priority['%']=3;
priority['+']=priority['-']=4;
priority[')']=5;
for(int i=0;i<str.size();i++){
if(isNum(str[i])) res.push_back(str.c_str()[i]);
else if(str[i]=='(') Sop.push(str.c_str()[i]);
else if(str[i]==')')
{
while(Sop.top()!='('){
res.push_back(Sop.top());
Sop.pop();
}
//remove '(' operator
Sop.pop();
}
else//是运算符
{
if(Sop.empty()) Sop.push(str.c_str()[i]);
else if(priority[str[i]]<priority[Sop.top()])
Sop.push(str.c_str()[i]);
else{
while(priority[str[i]]>=priority[Sop.top()])
{
if(Sop.top()=='(') break;
res.push_back(Sop.top());
Sop.pop();
if(Sop.empty()) break;
}
Sop.push(str.c_str()[i]);
}
}
}
while(!Sop.empty()){
res.push_back(Sop.top());
Sop.pop();
}
cout<<"size of the res is "<<res.size()<<endl;
}
int getValue(string expr)
{
int res=0;
stack<int> S;
while(!S.empty()) S.pop();
for(int i=0;i<expr.size();i++)
{
// cout<<"now is: "<<expr[i]<<endl;
if(isNum(expr[i])) S.push(expr[i]-'0');
else{
int a=S.top();S.pop();
int b=S.top();S.pop();
cout<<"now: "<<i<<" "<<expr[i]<<b<<endl;
if(expr[i]=='+') S.push(a+b);
else if(expr[i]=='-') S.push(b-a);
else if(expr[i]=='*') S.push(a*b);
else if(expr[i]=='/') S.push(b/a);
else if(expr[i]=='%') S.push(b%a);
else if(expr[i]=='^') S.push(int(pow(b,a)));
}
}
return S.top();
}
int main() {
string expression("4/2+(2*3-3*4)");
// string res="42/23*34*-+" ;
string res=NifixToSuffix(expression);
cout<<getValue(res)<<endl;
}