原理:
数据栈:有数据就直接入栈
运算符栈:设遍历到当前的运算符位e,如果栈不为空,比较栈顶与当前运算符优先级e,当栈顶运算符优先级大于或者等于e的优先级,则出栈,并将两个数据栈的数据出栈,计算出对应的数据,加入到数据栈中,否则将运算符入栈
#include <iostream>
#include <unordered_map>
#include <stack>
#include <functional>
#include <string>
#define MAX_PRI INT_MAX
using namespace std;
int main() {
//数据栈
stack<double> _data;
//运算符栈
stack<char> _operator;
//运算符优先级
unordered_map<char, int> pri{ {'+', 0}, {'-', 0}, {'*', 1},
{'/', 1}, {'^', 2}, {'(', MAX_PRI },
{')', MAX_PRI}};
unordered_map<char, function<double(double, double)>> func{
{'+', [](double x, double y) -> double { return x + y; }},
{'-', [](double x, double y) -> double { return x - y; }},
{'*', [](double x, double y) -> double { return x * y; }},
{'/', [](double x, double y) -> double { return x / y; }},
{'^', [](double x, double y) -> double { return pow(x, y); }}
};
string exp;
cin >> exp;
auto calculate = [&_data, &_operator, &func]() {
char op = _operator.top();
_operator.pop();
double x = _data.top();
_data.pop();
double y = _data.top();
_data.pop();
_data.push(func[op](y, x)); //运算顺序与出栈顺序相反
};
auto stringtonum = [&exp, &pri](int& i) -> double {
int j = i + 1;
while (j < exp.length() && pri.find(exp[j]) == pri.end()) j++;
double num = stod(exp.substr(i, j - i));
i = j - 1;
return num;
};
for (int i = 0; i < exp.length(); ++i) {
char e = exp[i];
if (pri.find(e) == pri.end()) { //当前字符不是运算符,则切割数字
_data.push(stringtonum(i));
} else if (e == '(') {
_operator.push('(');
} else if (e == ')') {
while (_operator.top() != '(') {
calculate();
}
_operator.pop();
} else {
//当前运算符优先级<=栈顶运算符优先级,则出栈计算
while (!_operator.empty() && pri[_operator.top()] >= pri[e] && _operator.top() != '(') {
calculate();
}
_operator.push(e);
}
}
while (!_operator.empty()) {
calculate();
}
cout << _data.top() << endl;
}