河南省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 后 ...
随机推荐
- docker 在 centos7.* 上的部署及问题解决
最近尝试搭建docker 环境,其实个人是比较喜欢“菜鸟学习系列”的知识的,怎奈它的讲解是以Ubuntu为主的,最后找到一个搭建学习系列,感觉写的很好,主要是页面风格清晰明了,遂决定按照此教程学习搭建 ...
- WXS-----学会使用WXS
学会使用WXS require函数用于引入其他WXS模块 不要重复引入两个wxs模块,不然后者会覆盖前者
- 初步了解 Netty
精通并发与 Netty (一)如何使用 精通并发与 Netty Netty 是一个异步的,事件驱动的网络通信框架,用于高性能的基于协议的客户端和服务端的开发. 异步指的是会立即返回,并不知道到底发送过 ...
- PS命令和kill命令
名称:ps使用权限:所有使用者使用方式:ps [options] [--help]说明:显示瞬间行程 (process) 的动态参数:ps的参数非常多, 在此仅列出几个常用的参数并大略介绍含义-A ...
- LeetCode 172. 阶乘后的零(Factorial Trailing Zeroes)
172. 阶乘后的零 172. Factorial Trailing Zeroes 题目描述 给定一个整数 n,返回 n! 结果尾数中零的数量. LeetCode172. Factorial Trai ...
- [转帖]Nginx Image Module图片缩略图 水印处理模块
Nginx Image Module图片缩略图 水印处理模块 https://www.cnblogs.com/jicki/p/5546972.html Nginx Image Module图片缩略图 ...
- 单源最短路——朴素Dijkstra&堆优化版
朴素Dijkstra 是一种基于贪心的算法. 稠密图使用二维数组存储点和边,稀疏图使用邻接表存储点和边. 算法步骤: 1.将图上的初始点看作一个集合S,其它点看作另一个集合 2.根据初始点,求出其它点 ...
- hyperledger fabric超级账本java sdk样例e2e代码流程分析
一 checkConfig Before 1.1 private static final TestConfig testConfig = TestConfig.getConfig() ...
- WUSTOJ 1349: TLE(Java)算法优化
题目链接:1349: TLE Description WH在刷题时,设计出了如下代码: #include<stdio.h> int main() { int i, j, cnt, k, N ...
- WUSTOJ 1318: 区间的连通性(Java)
题目链接: