用栈实现:
1、初始化两个栈:操作数栈、运算符栈
2、依次扫描
- 若扫描到操作数。压入操作数栈。
- 若扫描到运算符或界限符。按照“中缀转后缀”相同的逻辑压入运算符栈(期间也会弹出运算符,每当弹出一个运算符时,就需要再弹出两个操作数栈的栈顶元素并执行相应运算,运算结果再压入操作数栈)
具体实现:
#include<iostream>
#include<string>
#include<stack>
using namespace std;
stack<char> op;//运算符栈
stack<int> num;//操作数栈
int priority(char a){
if(a=='+'||a=='-') return 1;
if(a=='*'||a=='/') return 2;
if(a=='(') return 0;
}
void operate(){//进行一次操作
int b=num.top();//右操作数
num.pop();
int a=num.top();//左操作数
num.pop();
if(op.top()=='+') num.push(a+b);
if(op.top()=='-') num.push(a-b);
if(op.top()=='*') num.push(a*b);
if(op.top()=='/') num.push(a/b);
op.pop();
}
int main(){
string s;
cin>>s;
for(int i=0;i<s.length();i++){
if(s[i]>='0'&&s[i]<='9'){//操作数(可能不是个位数,比如12)
int j=i;
int x=0;//操作数
while(j<s.length()&&s[j]>='0'&&s[j]<='9'){
x=x*10+s[j++]-'0';
}
num.push(x);
i=j-1;//i指向整个操作数的个位数,然后i++后进入下一个
}else{
if(op.empty()) op.push(s[i]);
else if(s[i]=='('){//界限符
op.push(s[i]);
}else if(s[i]==')'){//界限符
while(op.top()!='('){
operate();//计算
}
//'('出栈
op.pop();
}else{//运算符
//栈顶元素的优先级>=当前
while(priority(op.top())>=priority(s[i])){
operate();
if(op.empty()) break;
}
op.push(s[i]);
}
}
}
//剩余
while(op.size()) operate();
cout<<num.top()<<endl;
return 0;
}