中缀转逆波兰
用一个栈装操作符
1、遇到数字就输出
2、遇到操作符,如果栈空直接放入,如果左括号直接放入,如果是右括号,输出并弹出栈顶直到遇到左括号,再把左括号弹出(不用输出),
如果是四则运算符,如果当前比栈顶优先级高,直接放入,否则输出并弹出所有优先级大于等于当前运算符的,再放入当前运算符。
最后将栈里剩下的元素输出弹出
逆波兰求值
每次弹两个,算一下,放回去,最后结果就是栈剩下的最后一个元素
#include<bits/stdc++.h>
using namespace std;
class Solution {
public:
int f(char c) { // 运算符的优先级
if(c == '*' || c == '/') {
return 2;
}
else if(c == '+' || c == '-') {
return 1;
}
return -1;
}
int calculate(string s) {
int n = s.size();
string suffix = "";
stack<char> op;
for(int i = 0; i < n; i++) {
if(s[i] == ' ') {
continue;
}
if('0' <= s[i] && s[i] <= '9') {
suffix.push_back(s[i]);
}
else { // 四个运算符
suffix.push_back(' ');
if(op.empty()) {
op.push(s[i]);
}
else{
if(s[i] == '(') {
op.push(s[i]);
}
else if(s[i] == ')') {
while(op.top() != '(') {
suffix.push_back(op.top());
op.pop();
}
op.pop();
}
else {
// 如果当前优先级更高,直接加入栈中
if(f(s[i]) > f(op.top())) {
op.push(s[i]);
}
else {
//弹出,直到栈顶优先级低于当前的优先级,再加入当前的运算符
while(!op.empty() && f(op.top()) >= f(s[i])) {
suffix.push_back(op.top());
op.pop();
}
op.push(s[i]);
}
}
}
}
}
suffix.push_back(' ');
while(!op.empty()) {
suffix.push_back(op.top());
op.pop();
}
cout<<suffix<<endl;
return calcSuffix(suffix);
}
int calcSuffix(string suffix) {
int n = suffix.size();
int num = 0; // 临时记录数据
stack<int> s; // 计算表达式的栈
bool flag = false;
for(int i = 0; i < n; i++) {
if(suffix[i] == ' ') {
cout<<"num="<<num<<endl;
if(flag) {
s.push(num);
}
num = 0;
flag = false;
}
else if('0' <= suffix[i] && suffix[i] <= '9') {
num = num * 10 + (suffix[i]-'0');
flag = true;
}
else if(suffix[i] == '+' || suffix[i] == '-' || suffix[i] == '*' || suffix[i] == '/'){
int x = s.top(); s.pop();
int y = s.top(); s.pop();
if(suffix[i] == '+') {
s.push(y+x);
}
else if(suffix[i] == '-') {
s.push(y-x);
}
else if(suffix[i] == '*') {
s.push(y*x);
}
else {
s.push(y/x);
}
}
}
return s.top();
}
};
int main() {
Solution s;
int res = s.calculate("1 + 2 + 3*4 + (5/6) -7");
cout<<"the answer is "<< res<<endl;
return 0;
}