河南省acm第九届省赛--《表达式求值》--栈和后缀表达式的变形--手速题
表达式求值
- 描述
- 假设表达式定义为:1. 一个十进制的正整数 X 是一个表达式。2. 如果 X 和 Y 是 表达式,则 X+Y, X*Y 也是表达式; *优先级高于+.3. 如果 X 和 Y 是 表达式,则 函数 Smax(X,Y)也是表达式,其值为:先分别求出 X ,Y值的各位数字之和,再从中选最大数。4.如果 X 是 表达式,则 (X)也是表达式。 例如:表达式 12*(2+3)+Smax(333,220+280) 的值为 69。 请你编程,对给定的表达式,输出其值。
- 输入
- 【标准输入】 第一行: T 表示要计算的表达式个数 (1≤ T ≤ 10) 接下来有 T 行, 每行是一个字符串,表示待求的表达式,长度<=1000
- 输出
- 【标准输出】 对于每个表达式,输出一行,表示对应表达式的值。
- 样例输入
-
3
12+2*3
12*(2+3)
12*(2+3)+Smax(333,220+280) - 样例输出
-
18
60
69 - 来源
- 河南省第九届省赛
-
大致思路:
- 用stack来实现的后缀表达式的解法。
- 每次需要考虑运算符的优先级,怎么考虑?
- 分类讨论:
- 1、顺序遍历表达式,当前符号位为加号时,判断上一位,是加号(同级),取num栈两个栈顶元素和op栈栈顶符号进行一次运算,再放回num栈中。
- 2、当前符号位为乘号,如果乘号的前后都是数字——那么一定可以进行乘法运算一次;由于在顺序遍历数组时,不方便预知后面一位是否为数字,可以在每次读入一位数字后进行判断;乘号的前后都是数字时,可以放心做乘。
- 3、当前符号位为S,Smax可以特殊处理,不存入“Smax”,只保留中间的', ' 即可!把', ' 号当做特殊运算符(类似与‘*’和‘+’)。
- 4、遇见左括号,存入;遇见右括号,开始进行计算一直计算到左括号,并把左括号删除。还有就是第三步', '的左右,进行运算时——要确保‘,’左右两边都是一个确定的数值!不然没法运算,所以对‘,’左边必须进行处理成一个整数!
- 5、加强版的样例 :
-
21
1+2
1+2+3
12*3+4*1*2
12*(1+3*4+1)12*(2+3*1)+Smax(333,220*1+280)
12*(2+3)+(1+1*333,220*1+280)题解:(有稍微的注释)
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<stdlib.h>
#include<map>
#include<stack>
#include<queue>
#define inf 0x3f3f3f3f//19:04--
#define N 1008
#define ll long long
using namespace std;
stack<int>num;
stack<char>op;
char str[N];
void cal(char opx){//依据opx来计算num栈上的前两位
if(num.size()<=)return ;
int n1,n2;
n1=num.top();num.pop();
n2=num.top();num.pop();
if(opx=='*')
num.push(n1*n2);
else if(opx=='+')
num.push(n1+n2);
else if(opx==','){
int s1=,s2=;
while(n1>){
s1+=n1%;n1/=;
}
while(n2>){
s2+=n2%;n2/=;
}
num.push(max(s1,s2));
}
}
void cal2(char opx){//计算到左括号为止(Smax可以特殊处理:只保留中间的','即可!把','号当做特殊运算符)
if(opx==','){
while(op.top()!='('){
cal(op.top());
op.pop();
}
// op.pop(); }else{
while(op.top()!='('){
cal(op.top());
op.pop();
}
op.pop();//去掉左括号
}
}
int get_nextnum(int i){//分离出从str[]数组下标i开始的数字,注意要返回j
int j,sum=str[i]-'';
for(j=i+;j<strlen(str);j++){
if(str[j]>=''&&str[j]<='')
sum=sum*+str[j]-'';
else
break;
}
num.push(sum);
return j;
} void solve(){
int ans=;
int len=strlen(str);
for(int i=;i<len;){
if(str[i]==' ')
i++;
else if(str[i]>=''&&str[i]<=''){
i=get_nextnum(i);//获取该位置数字
if(!op.empty()&&op.top()=='*'){//当读入一个数字后,发现上一位是乘号:及时做乘
cal('*');
op.pop();
}
}
else if(str[i]=='*'){
op.push('*');
i++;
}
else if(str[i]=='+'){
if(!op.empty()&&op.top()=='+'){
cal(str[i]);//可以省略一push一次‘+’,毕竟先pop‘+’后push‘+’
}
else if(!op.empty()&&op.top()=='*'){
cal('*');
op.pop();
op.push('+');
}
else
op.push('+');
i++;
}
else if(str[i]=='S'){
i+=;
}
else if(str[i]==','){
cal2(',');//计算到左括号!
op.push(str[i++]);
}
else if(str[i]=='('){
op.push(str[i++]);
}
else if(str[i]==')'){
cal2(')');
i++;
}
} while(op.size()>=){
cal(op.top());
op.pop();
} ans=num.top(); printf("%d\n",ans);
} int main(){
int T;
scanf("%d\n",&T); while(T--){
while(num.size()>)num.pop();//清空整个num栈和op栈
while(op.size()>)op.pop();
gets(str);
solve();
} return ;
}
河南省acm第九届省赛--《表达式求值》--栈和后缀表达式的变形--手速题的更多相关文章
- 第四届河南省ACM 表达式求值 栈
表达式求值 时间限制: 1 Sec 内存限制: 128 MB 提交: 14 解决: 7 [提交][状态][讨论版] 题目描述 Dr.Kong设计的机器人卡多掌握了加减法运算以后,最近又学会了一些简 ...
- 表达式求值(noip2015等价表达式)
题目大意 给一个含字母a的表达式,求n个选项中表达式跟一开始那个等价的有哪些 做法 模拟一个多项式显然难以实现那么我们高兴的找一些素数代入表达式,再随便找一个素数做模表达式求值优先级表 - ( ) + ...
- 表达式求值 (栈) 用C++实现
#include <cstdio> #include <cstdlib> #include <cmath> #include <stack> #incl ...
- Python解析 算数表达式求值 栈的使用
使用Python实现一种算数表达式求值的算法,模拟这种使用栈的方式,这是由E.W.Dijkstra在20世纪60年代发明的一种非常简单的算法.代码模拟仅仅表现一种编程思想,代码的逻辑并不完全: if ...
- 2015 UESTC 数据结构专题N题 秋实大哥搞算数 表达式求值/栈
秋实大哥搞算数 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/1074 Des ...
- 【zzuli-1923】表达式求值
题目描述 假设表达式定义为:1. 一个十进制的正整数 X 是一个表达式.2. 如果 X 和 Y 是 表达式,则 X+Y, X*Y 也是表达式; *优先级高于+.3. 如果 X 和 Y 是 表达式,则 ...
- C语言中缀表达式求值(综合)
题前需要了解的:中缀.后缀表达式是什么?(不知道你们知不知道,反正我当时不知道,搜的百度) 基本思路:先把输入的中缀表达式→后缀表达式→进行计算得出结果 栈:"先进先出,先进后出" ...
- NYOJ 1272 表达式求值 第九届省赛 (字符串处理)
title: 表达式求值 第九届省赛 nyoj 1272 tags: [栈,数据结构] 题目链接 描述 假设表达式定义为: 1. 一个十进制的正整数 X 是一个表达式. 2. 如果 X 和 Y 是 表 ...
- java实现算术表达式求值
需要根据配置的表达式(例如:5+12*(3+5)/7.0)计算出相应的结果,因此使用java中的栈利用后缀表达式的方式实现该工具类. 后缀表达式就是将操作符放在操作数的后面展示的方式,例如:3+2 后 ...
随机推荐
- 切实解决socket连接掉线检测
原文:切实解决socket连接掉线检测 版权声明:欢迎转载,但是请保留出处说明 https://blog.csdn.net/lanwilliam/article/details/51698807 新公 ...
- NLP | 算法 学习资料整理
UPDATE TIME: 2019-12-12 17:06:32 NLP: 对话系统: [ ] https://www.cnblogs.com/jiangxinyang/p/10789512.html ...
- QPS、TPS和系统吞吐量
QPS:Queries Per Second,每秒查询率.是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准. TPS:Transactions Per ...
- 025 Android 带进度条的对话框(ProgressDialog)
1.ProgressDialog介绍 ProgressDialog可以在当前界面弹出一个置顶于所有界面元素的对话框,同样具有屏蔽其他控件的交互能力,用于提示用户当前操作正在运行,让用户等待: 2.应用 ...
- PAT(B) 1052 卖个萌(Java:0分 待解决,C:20分)
题目链接:1052 卖个萌 (20 point(s)) 题目描述 萌萌哒表情符号通常由"手"."眼"."口"三个主要部分组成.简单起见,我们 ...
- 自定义AuthorizeFilter
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization.Infrastructure; u ...
- source tree每次push都需要密码的解决方法
Windows首先可以考虑使用GitHub for Windows,它已经包含了该助手,或者可以下载对应系统的版本:Windows 7.Windows 8.Source 版本,然后解压缩文件并将里面的 ...
- ubuntu下使用JNI Java调用C++的例子
TestJNI.java public class TestJNI { static{ System.load("/home/buyizhiyou/workspace/JNI/src/lib ...
- MACOS 安装mysqlclient 的 Library not loaded错误
报错场景 >>> import MySQLdb Traceback (most recent call last): File "<stdin>", ...
- PLSQL登录的时候Warning提示:Using a filter for all users can lead to poor performance!
转自: https://blog.csdn.net/athena2015/article/details/81811908