一、表达式求值的概念
算术表达式由操作、运算符组成,在计算机中进行算术表达式的计算是通过堆栈来实现的。通常两个栈就能实现表达式求值。
二、计算机中的表达式求值
1.计算机采用从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,将运算符压入另一个堆栈。
2.其中涉及一个运算符号优先级的问题。如图:
(图片来自百度)
(1) 先计算括号内,后计算括号外;
(2) 在无括号或同层括号内,先乘除运算,后加减运算,即乘除运算的优先级高于加减运算的优先级;
(3) 同一优先级运算,从左向右依次进行。
3.在引入运算符号优先级的概念后。计算机将逐个字符分析表达式,直到全部字符都已分析完。
(1)若当前字符为数字,则判断是否后续字符也为数字,若为数字则进行拼接,直到下一个数字为运算符为止,此时将拼接好的多位数字压入数字栈中。(如果已经是最后一个字符则直接压入栈)
(2)若当前字符为算数运算符,如果运算符栈为空则直接压入栈中,运算符不为空,则对运算符优先级进行判断,如果当前运算符优先级大于等于栈顶运算符则直接压入栈中。如果优先级低于栈顶运算符,则从数字栈中取出两个数据,将当前栈顶运算符弹出进行运算,将结果压入数字栈中,将当前运算符压入运算符栈中。此时数字与运算符都已经压入栈中,此时运算符栈中均为优先级相同的运算符需要进行收尾操作,如果运算符栈不为空,则依次从数字栈中弹出两个数据,与当前栈顶的运算符进行运算。将结果压入数字栈中。最后数字栈中的数字就是所要求解的结果。
代码如下:
#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;
cin >> str;
for (int i = 0; i < str.size(); i++)
{
auto c = str[i];
if (isdigit(c))
{
int x = 0, j = i;
while (j < str.size() && isdigit(str[j]))
x = x * 10 + str[j++] - '0';
i = j - 1;
num.push(x);
}
else if (c == '(') op.push(c);
else if (c == ')')
{
while (op.top() != '(') eval();
op.pop();
}
else
{
while (op.size() && op.top() != '(' && pr[op.top()] >= pr[c]) eval();
op.push(c);
}
}
while (op.size()) eval();
cout << num.top() << endl;
return 0;
}
运行如下:![](https://img-blog.csdnimg.cn/90b903379b1e48dbaaa7eacbead607bb.png)