中缀表达式计算
中缀表达式需要考虑操作符的优先级,优先级高的必须先计算,有括号就计算括号内的,因此可以使用栈来模拟中缀表达式的计算过程。
具体操作
- 需要两个栈,一个存储数字,一个存储操作符。
- 当操作符的栈外优先级高于栈内优先级时操作符入栈,否则弹出当前栈顶元素进行操作后再比较优先级的高低,当栈外优先级高于栈内优先级时入栈。
- 当出现 ‘ ( ’ 时直接入栈,出现 ’ ) ‘ 时依次出栈,直到栈顶元素为 ’ ( '。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<stack>
#include<unordered_map>
using namespace std;
//存储运算数 运算符
stack<int> num;
stack<char> op;
//模拟一次算术操作
void eval()
{
auto b = num.top(); num.pop();
auto a = num.top(); num.pop();
auto c = op.top(); op.pop();
int x = 0;
if(c == '+') x = a + b;
else if(c == '-') x = a - b;
else if(c == '*') x = a * b;
else if(c == '/') x = a / b;
num.push(x);
}
int main()
{
//建立映射来判断运算优先级
unordered_map<char, int> pr = {{'+',1},{'-',1},{'*',2},{'/',2}};
string str;
cin >> str;
for(int i = 0; i < str.size(); i ++)
{
//读入运算数
auto c = str[i];
if(isdigit(c))
{
int j = i, x = 0;
while(j < str.size() && isdigit(str[j]))
{
x = x * 10 + str[j ++] - '0';
}
i = j - 1; //由于每轮循环有i++,防止越界
num.push(x);
}
else if(c == '(') op.push(c); //左括号的优先级最低直接入栈
else if(c == ')') //右括号的优先级,先算括号
{
while(op.top() != '(') eval();
op.pop(); //左括号可以弹出
}
else
{
//这里必须得带等于号 0 - 5 + 3 优先级判断没加=号,上式会被错误计算成 -8
while(op.size() && op.top() != '(' && pr[op.top()] >= pr[c]) eval();
op.push(c); //当前栈外运算符优先级高于栈内,压入新运算符
}
}
//清理剩余的低优先级操作
while(op.size()) eval();
cout << num.top() << endl;
return 0;
}