
点击查看代码
#include<iostream>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
stack<int> nums;
stack<char> op;
unordered_map<char, int> h{ {'+', 1}, {'-', 1}, {'*', 2}, {'/', 2} };
void eval()
{
int b = nums.top(); nums.pop();
int a = nums.top(); nums.pop();
char p = op.top(); op.pop();
int r = 0;
if (p == '+') r = a + b;
if (p == '-') r = a - b;
if (p == '*') r = a * b;
if (p == '/') r = a / b;
nums.push(r);
}
int main()
{
string s;
cin >> s;
for (int i = 0; i < s.size(); i ++) {
if (isdigit(s[i])) {
int x = 0, j = i;
while (j < s.size() && isdigit(s[j])) {
x = x * 10 + s[j] - '0';
j ++;
}
nums.push(x);
i = j - 1;
}
else if (s[i] == '(') op.push(s[i]);
else if (s[i] == ')') {
while (op.top() != '(') eval();
op.pop();
}
else {
while (op.size() && h[op.top()] >= h[s[i]]) eval();
op.push(s[i]);
}
}
while (op.size()) eval();
cout << nums.top();
return 0;
}
- 用字符串进行读入,对每一位字符进行如下操作:
① 如果当前位置是数字,使用 while 获取所有的数字部分,直到遇到负号,用 x 存下数字,push 到 nums 中,然后 i = j - 1(需要 -1 是因为 for 循环会执行 i ++);
② 如果当前位置是 '(',把 '(' 放到 op 中;
③ 如果当前位置是 ')',则从 op 中弹出操作符,直到遇到 '(',每次使用 eval 弹出操作符和 2 个数字,并计算当前操作符和 2 个数字的运算结果 r,将 r 放到 nums 中;
④ 当前位置 s[ i ] 是字符且不为 '(' ' )', op 栈顶元素的优先级比 s[ i ] 的优先级要高,则需要使用 eval 弹出比 s[ i ] 优先级高的操作符进行运算,最后把 s[ i ] 放到栈顶;
- 如果最后 op 不为空,则需要把 op 里面的操作符都弹出来进行运算;
- 最终的结果会存在 nums 中;
- eval 操作的注意事项:
① nums 中弹出数时,先弹出的是 b,后弹出的是 a( a - b,a / b );
② 从 nums 和 op 这两个栈中弹出元素时,先 top( ) 取出栈顶元素,再用 pop( ) 弹出;
- 使用 unordered_map<char, int> h 来维护操作符的优先级;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!