AcWing 3302. 表达式求值
原题链接
简单
作者:
满目星河_0
,
2021-03-31 12:27:26
,
所有人可见
,
阅读 172
带注释(超详细)
//算法思想:定义两个栈,其中一个用来存储运算符,一个用来存储运算中的数字。
//定义一个哈希表,用来表示各个运算符的优先级。
#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;
//进行运算
if (c == '+') x = a + b;
else if (c == '-') x = a - b;
else if (c == '*') x = a * b;
else x = a / b;
num.push(x); //将计算完的结果加入数字栈,用于下部计算。
}
int main()
{
unordered_map<char, int> pr{{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};
string str; //表达式是string类型
cin >> str;
for (int i = 0; i < str.size(); i ++ )//遍历表达式
{
auto c = str[i]; //c表示当前字符
if (isdigit(c)) //如果当前字符是数字
{
int x = 0, j = i;
while (j < str.size() && isdigit(str[j])) //有可能是多位数字,所以用whiole循环来赋值
x = x * 10 + str[j ++ ] - '0'; //当前数字赋值为x
i = j - 1;
num.push(x); //将当前数字加入栈
}
else if (c == '(') op.push(c); //如果是左括号,入栈
else if (c == ')')
{//如果遇到了右括号,不用入栈,不断地进行计算,直至计算到左括号,并且弹出左括号。
while (op.top() != '(') eval();
op.pop();
}
else //如果是其他运算符
{//如果栈不空且栈顶元素的运算符优先级比当前正在遍历到的运算符的优先级更高,则进行eval,即从
//符号栈和数字栈弹出元素进行计算。
while (op.size() && op.top() != '(' && pr[op.top()] >= pr[c]) eval();
op.push(c); //如果不满足上述的判断条件,将运算符入栈。
}
}
while (op.size()) eval(); //如果运算符的栈不为空,就弹出元素进行计算。
cout << num.top() << endl; //最后输出数字栈的栈顶元素就是结果。
return 0;
}