3302. 表达式求值

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.

题目

链接如下:

3302. 表达式求值 - AcWing题库

给定一个表达式,其中运算符仅包含 +,-,*,/(加 减 乘 整除),可能包含括号,请你求出表达式的最终值。

注意:

  • 数据保证给定的表达式合法。
  • 题目保证符号 - 只作为减号出现,不会作为负号出现,例如,-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;
}









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值