3302. 表达式求值
Thank you for choosing Typora. This document will help you to start Typora. Please note that Typora for Windows is still in beta phase, so this document may be updated in future version-ups.
题目
链接如下:
给定一个表达式,其中运算符仅包含 +,-,*,/
(加 减 乘 整除),可能包含括号,请你求出表达式的最终值。
注意:
- 数据保证给定的表达式合法。
- 题目保证符号
-
只作为减号出现,不会作为负号出现,例如,-1+2
,(2+2)*(-(1+1)+2)
之类表达式均不会出现。 - 题目保证表达式中所有数字均为正整数。
- 题目保证表达式在中间计算过程以及结果中,均不超过 231−1231−1。
- 题目中的整除是指向 00 取整,也就是说对于大于 00 的结果向下取整,例如 5/3=15/3=1,对于小于 00 的结果向上取整,例如 5/(1−4)=−15/(1−4)=−1。
- C++和Java中的整除默认是向零取整;Python中的整除
//
默认向下取整,因此Python的eval()
函数中的整除也是向下取整,在本题中不能直接使用。
输入格式
共一行,为给定表达式。
输出格式
共一行,为表达式的结果。
数据范围
表达式的长度不超过 105105。
输入样例:
(2+2)*(1+1)
输出样例:
8
题解
设立两个栈;
一个栈用于储存输入的数字,一个用于储存运算符;
跟后缀表达式不同的式,这里的中缀表达式是可以用括号改变运算优先级的,所以我们要在运算符栈里考虑括号的情况;
下面的解法是参考这篇题解的:
AcWing 3302. 表达式求值:多图讲解运算符优先级+详细代码注释 - AcWing
#include<iostream>
#include<stack>
#include<string>
#include<unordered_map>
#include<algorithm>
#include<vector>
using namespace std;
stack<int> num;
stack<char> op;
//运算符的优先级
unordered_map<char,int> h{
{'+' , 1},{'-' , 1},{'*' , 2},{'/' , 2}
} ;
void eval()//求值
{
int a = num.top();
num.pop();
int b = num.top();
num.pop();
char p = op.top();
op.pop();
int r = 0 ;
if(p == '+') r = a + b;
if(p == '-') r = b - a;
if(p == '*') r = b * a;
if(p == '/') r = b / a;
num.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]))//j指针走,直到扫到不是运算符的地方
{
x = x * 10 + s[j] - '0';
j++;
}
//巧妙的写法,高位数字向低位数字扫描,*10是为了进位;
//s[j] - '0' 强制转换;
num.push(x);
i = j - 1;
}
//左括号直接入栈
else if(s[i] == '('){
op.push(s[i]);
//TODO
}
//遇到右括号开始计算括号里面的
else if(s[i] == ')')
{
while(op.top() != '(')
eval();
op.pop();
}
else
{
while(op.size() && h[op.top()] >= h[s[i]]){
eval();
//TODO
}
op.push(s[i]);
}
}
while(op.size())eval();
cout<<num.top()<<endl;
}