AcWing 3302. 表达式求值

题面:给定一个表达式,其中运算符仅包含加减乘除,可能包含括号,请你求出表达式的最终值。

原题链接:3302. 表达式求值 - AcWing

基本思路

  • 创建两个栈,分别存储数字和运算符
  • 运算符的判定:仅在以下条件满足时将运算符直接压入栈中:
    ①栈中不存在元素 ②当前运算符优先级比栈顶高 ③栈顶为左括号
    其他情况下,取出栈顶优先级较高的运算符,与数字栈顶两元素,先行计算
  • 括号的判定:当遇到右括号时,将括号内表达式优先计算
    为什么此时不需要考虑运算符优先级的问题?因为此时括号内均为同一优先级

两个核心关键点

  1. 双栈:一个操作数栈,一个运算符栈;
  2. 运算符优先级:栈顶运算符,和,即将入栈的运算符的优先级比较。
#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
string str;
stack<int> num;
stack<char> op;
//也可以写为优先级表
unordered_map<char, int> h{ {'+', 1}, {'-', 1}, {'*',2}, {'/', 2} };
//判断运算符优先级
//int prior(char op) {
// if (op == '+' || op == '-')
// return 1;
// if (op == '*' || op == '/')
// return 2;
// return 0;
//}
//弹出栈顶运算符,进行计算
void calculate(stack<int>& num, stack<char>& op, char opr) {
int top = num.top();
num.pop();
int sec = num.top();
num.pop();
if (opr == '+') sec += top;
if (opr == '-') sec -= top;
if (opr == '*') sec *= top;
if (opr == '/') sec /= top;
num.push(sec);
op.pop();
}
//初始化数字栈,运算符栈中只保留同一优先级的运算符
void init(stack<int>& num, stack<char>& op) {
//for (size_t i = 0; str[i] != '='; i++)
//不需要size_t也能正确计算数字的做法
for (int i = 0; i < str.size() ; i++) {
if (isdigit(str[i])) { //将字符串转换为数字并入数字栈
double x = 0;
int j = i; //保存指针
while (i < str.size() && isdigit(str[j]))
x = x * 10 + str[j++] - '0';
num.push(x);
i = --j;
}
else if (str[i] == '(')
op.push(str[i]);
else if (str[i] == ')') { //优先计算括号中表达式
while (!op.empty() && op.top() != '(')
calculate(num, op, op.top());
op.pop();
}
else {
//待入栈运算符优先级低,则先计算
while (!op.empty() && h[str[i]] <= h[op.top()])
calculate(num, op, op.top());
op.push(str[i]);
}
}
}
//此时运算符只有相同优先级,即加减,一次性计算完毕
int finalCal(stack<int>& num, stack<char>& op) {
while (!op.empty())
calculate(num, op, op.top());
return num.top();
}
int main()
{
cin >> str;
init(num, op);
cout << finalCal(num, op);
return 0;
}

  1. https://www.acwing.com/solution/content/40978/ ↩︎

posted @   蒟蒻爬行中  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示