ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

表达式求值

2021-07-30 17:32:45  阅读:120  来源: 互联网

标签:2527 top st 括号 求值 now 表达式


表达式求值常常是cxy的一大烦恼。总是会出各种错误,究竟该怎么办?今天,我来讲解一下我写的魔鬼版本——栈。

〇、题面

问题描述

给定一个只包含加(+)、减(-)、乘(*)三种运算的\(n\)个字符的合法表达式,请求出该表达式的值对\(2527\)取余后的结果。

输入格式

第一行输入一个字符串\(S\),表示一个合法表达式。

输出格式

输出一个整数,表示该表达式的值对\(2527\)取余后的结果。

样例输入1

(26*3*8)+(1*11)-(9*15*9)

样例输出1

1947

样例输入2

(510*510+208)-(511*511-813)

样例输出2

0

评测用例规模与约定

\(1\leq |S|\leq 5\times 10^6\) ,其中\(|S|\)为字符串\(S\)的长度。

保证表达式仅包含数字、左右括号、加号、减号、乘号,且表达式中的数字均为整数且\(\in [0,2527)\)。

一、栈思想

我因为过于辣鸡,只好用了一个栈存数与符号。
可是一个栈怎么同时存数与符号呢?机智的我把2528认作+,把2529认作-,把2529认作*,把2529认作(。至于为什么没有),后面再说。
可恶的数据竟然出现了超过2527的数,于是我后面代码里都在前面加了一个2(在此感谢hjy同学的猜测)。

每次对于一个字符,我们分类讨论:

  1. 如果他是数字,加在前面的数字里,继续往后;
  2. 如果是加减乘和右括号,说明数已经输入完毕,进入情况1,然后把数推入栈。(左括号前面肯定有符号)
  3. 如果是加减乘和左括号,就把他们推入栈中。
  4. 右括号进入情况2。

情况1:
因为数读入完了,所以我们需要处理一下。如果栈顶此时是乘号,那弹出栈顶,把新栈顶变为新栈顶乘输入完的数。这样,右括号处理时就只需要加减法了。
不是乘号,直接放入栈中。
之后(代码里可以搞清楚),清空存储数的东西。
情况2:
现在这个括号结束了,经过上面的整合只剩下一堆加减,方便极了。这里贴代码:

if(c==')'){
	n2=0;//n2表示当前数
	while(st.top()!=22531){//22531是左括号
		n2=st.top();//首先获取当前数
		st.pop();//弹掉这个数
		if(st.top()==22529) now-=n2;//减法,即...-XXX...
		else now+=n2;//加法...+XXX...
		now%=2527;//取余
		if(st.top()!=22531) st.pop();//只要没有到结束(要留着)就去掉符号
	}
	st.pop();//去掉左括号
	if(!st.empty()&&st.top()==22530){//非空且是乘号
		st.pop();//弹出乘号
		now*=st.top();//乘上
		now%=2527;//取余
		st.pop();//弹出这个数
	}
	st.push(now);//再把一通计算的结果放进去
	now=0;//恢复出厂设置
	continue;//跳过后面
}

二、代码(无注释)

#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
stack<int> st;//22528=+,22529=-,22530=*,22531=(
int main(){
	ios::sync_with_stdio(0);
	string s;
	char c;
	cin>>s;
	int l=s.size(),now=0,n2;
	bool get=0;
	st.push(22531);
	s+=')';
	for(int i=0;i<=l;i++){
		c=s[i];
		if(c=='+'||c=='-'||c=='*'||c==')'){
			if(st.top()==22530){
				st.pop();
				now*=st.top();
				now%=2527;
				st.pop();
			}
			if(get) st.push(now);
			now=0;
			get=0;
		}
		if(c=='+') st.push(22528);
		if(c=='-') st.push(22529);
		if(c=='*') st.push(22530);
		if(c=='(') st.push(22531);
		if(c==')'){
			n2=0;
			while(st.top()!=22531){
				n2=st.top();
				st.pop();
				if(st.top()==22529) now-=n2;
				else now+=n2;
				now%=2527;
				if(st.top()!=22531) st.pop();
			}
			st.pop();
			if(!st.empty()&&st.top()==22530){
				st.pop();
				now*=st.top();
				now%=2527;
				st.pop();
			}
			st.push(now);
			now=0;
			continue;
		}
		if(c>='0'&&c<='9'){
			now=now*10+(c-'0');
			get=1;
		}
	}
	cout<<((st.top()%2527)+2527)%2527<<endl;
	int _=0;
	return ~~(0^_^0);
}

-完结撒花-

标签:2527,top,st,括号,求值,now,表达式
来源: https://www.cnblogs.com/tigerchen/p/15080658.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有