nyoj 409——郁闷的C小加(三)——————【中缀式化前缀后缀并求值】
郁闷的C小加(三)
- 描述
- 聪明的你帮助C小加解决了中缀表达式到后缀表达式的转换(详情请参考“郁闷的C小加(一)”),C小加很高兴。但C小加是个爱思考的人,他又想通过这种方法计算一个表达式的值。即先把表达式转换为前缀和后缀表达式,再求值。这时又要考虑操作数是小数和多位数的情况。
- 输入
- 第一行输入一个整数T,共有T组测试数据(T<10)。
每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以“=”结束。这个表达式里只包含+-*/与小括号这几种符号。其中小括号可以嵌套使用。数据保证输入的操作数中不会出现负数并且小于1000000。
数据保证除数不会为0。 - 输出
- 对于每组测试数据输出结果包括三行,先输出转换后的前缀和后缀表达式,再输出计算结果,结果保留两位小数。
- 样例输入
-
2
1+2=
(19+21)*3-4/5= - 样例输出
-
+ 1 2 =
1 2 + =
3.00
- * + 19 21 3 / 4 5 =
19 21 + 3 * 4 5 / - =
119.20#include<bits/stdc++.h>
using namespace std;
stack<char>S_tr;//用作后缀表达式运算符存储和前缀表达式存储数字
stack<double>S_nd;//用作存储操作数
stack<char>S_pre_optr;//用作前缀表达式计算中运算符存储
stack<string>S_pre_exp;//用以存放前缀表达式
char suf_exp[1200],suf_exp_i[1200],pre_str[1200];
int m,k,pos;
char suf_compare(char op1,char op2){//转后缀表达式时,比较优先级
// printf(".%c%c.\n",op1,op2);
if(op1=='+'||op1=='-'){
if( op2=='(' || op2=='*' || op2=='/')
return '<';
else return '>';
}
if(op1=='*'||op1=='/'){
if(op2=='(')
return '<';
else return '>';
}
if(op1=='='||op1=='('){
if((op1=='='&&op2=='=')||(op1=='('&&op2==')')){
return '=';
}else{
return '<';
}
}
}
char pre_compare(char a,char b){//转前缀表达式时,比较优先级
if(a=='+'||a=='-'){
if(b=='('||b=='='){
return '>';
}else{
return '<';
}
}
if(a=='*'||a=='/'){
if(b==')'||b=='*'||b=='/'){
return '<';
}else{
return '>';
}
}
if(a==')'||a=='='){
if(a==')'&&b=='('||a=='='&&b=='='){
return '=';
}else{
return '<';
}
}
}
void suf_solve(char a,char b){//求后缀表达式时,当栈顶>当前运算符优先级
if(suf_compare(a,b)=='>'){
suf_exp[m++]=a;//后缀表达式中出现的所有的运算符都在这里放入数组,所以在此加空格
suf_exp[m++]=' ';
suf_exp_i[k++]=a;
S_tr.pop();
suf_solve(S_tr.top(),b);
}else if(suf_compare(a,b)=='<'){
S_tr.push(b);
return;
}else{
S_tr.pop();
return ;
}
}
void pre_solve(char a,char b){//求前缀表达式时,当栈顶>当前运算符优先级
if(pre_compare(a,b)=='>'){
string ts="";
ts+=a;
S_pre_exp.push(ts);
S_pre_optr.pop();
pre_solve(S_pre_optr.top(),b);
}
if(pre_compare(a,b)=='<'){
S_pre_optr.push(b);
return ;
}
if(pre_compare(a,b)=='='){
S_pre_optr.pop();
return;
}
}
double get_num(int po,int len){ //提取数字
double ret=0;
int temp=0,tmp=1,integ=-1;
for(int i=po;i<len;i++){
if(suf_exp[i]==' '||suf_exp[i]=='\0'){
pos=i;
break;
}
if(suf_exp[i]=='.'){
integ=temp;
temp=0;
tmp=1;
continue;
}else{
int tm=suf_exp[i]-'0';
temp*=10;
temp+=tm;
tmp*=10;
}
}
if(integ!=-1)
ret=integ*1.0+temp*1.0/tmp;
else ret=temp*1.0;
return ret;
}
int main(){
int t;
char mid_exp[1200];
scanf("%d",&t);
while(t--){
while(!S_tr.empty()){
S_tr.pop();
}
while(!S_nd.empty())
S_nd.pop();
S_tr.push('=');
m=0;
k=0;
scanf("%s",mid_exp);
int len=strlen(mid_exp);
bool flag=0;
for(int i=0;i<len;i++){
if(mid_exp[i]>='0'&&mid_exp[i]<='9'||mid_exp[i]=='.'){
suf_exp[m++]=mid_exp[i];
suf_exp_i[k++]=mid_exp[i];
flag=1;
}
else{
if(flag==1){
suf_exp[m++]=' ';
flag=0;
}
switch(suf_compare(S_tr.top(),mid_exp[i])){
case '<': S_tr.push(mid_exp[i]);break;
case '>': suf_solve(S_tr.top(),mid_exp[i]);break;
case '=': S_tr.pop();break;
}
}
}
suf_exp_i[k]='\0';
suf_exp[m]='\0';
m++;
strcpy(pre_str+1,mid_exp);
while(!S_tr.empty())
S_tr.pop();
while(!S_pre_exp.empty())
S_pre_exp.pop();
string pre_;
bool flg=0;
pre_str[0]='=';
S_pre_optr.push('=');
for(int i=len-1;i>=0;i--){
if(pre_str[i]>='0'&&pre_str[i]<='9'||pre_str[i]=='.'){
flg=1;
S_tr.push(pre_str[i]);
}else{
if(flg==1){
flg=0;
pre_="";
while(!S_tr.empty()){
pre_+=S_tr.top();
S_tr.pop();
}
S_pre_exp.push(pre_);
}
switch(pre_compare(S_pre_optr.top(),pre_str[i])){
case '<' :S_pre_optr.push(pre_str[i]);break;
case '>' :pre_solve(S_pre_optr.top(),pre_str[i]);break;
case '=' :S_pre_optr.pop(); break;
default : break;
}
}
}
while(!S_pre_exp.empty()){
cout<<S_pre_exp.top()<<" ";
S_pre_exp.pop();
}printf("=");
cout<<endl;
double a,b;
for(int i=0;i<m;i++){
if(suf_exp[i]>='0'&&suf_exp[i]<='9'){
S_nd.push(get_num(i,m));
i=pos;
}else{
switch(suf_exp[i]){ //printf("%.3lf %.3lf\n",a,b);
case '+': b=S_nd.top(),S_nd.pop();a=S_nd.top(),S_nd.pop();S_nd.push(a+b);break;
case '-': b=S_nd.top(),S_nd.pop();a=S_nd.top(),S_nd.pop();S_nd.push(a-b);break;
case '*': b=S_nd.top(),S_nd.pop();a=S_nd.top(),S_nd.pop();S_nd.push(a*b);break;
case '/': b=S_nd.top(),S_nd.pop();a=S_nd.top(),S_nd.pop();S_nd.push(a/b);break;
default : break;
}
}
}
printf("%s%c\n",suf_exp,'=');
printf("%.2lf\n",S_nd.top());
S_nd.pop();
printf("\n");
}
return 0;
}
/*
5
1+((2+3)*4)-5= (19+21)*3-4/5=
9+(3-1)*3+10/2= */
nyoj 409——郁闷的C小加(三)——————【中缀式化前缀后缀并求值】的更多相关文章
- NYOJ 409 郁闷的C小加(三) (字符串处理)
题目链接 描述 聪明的你帮助C小加解决了中缀表达式到后缀表达式的转换(详情请参考"郁闷的C小加(一)"),C小加很高兴.但C小加是个爱思考的人,他又想通过这种方法计算一个表达式的值 ...
- NYOJ 257 郁闷的C小加(一) (字符串处理)
题目链接 描述 我们熟悉的表达式如a+b.a+b(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说)操作符在两个操作数中间:num1 operand num2.同理,后缀表达式就是操作符 ...
- NYOJ 257 郁闷的C小加(一)
郁闷的C小加(一) 时间限制:1000 ms | 内存限制:65535 KB 难度: 描写叙述 我们熟悉的表达式如a+b.a+b*(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说) ...
- nyoj 257 郁闷的C小加(一)(栈、队列)
郁闷的C小加(一) 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 我们熟悉的表达式如a+b.a+b*(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说 ...
- NYOJ 267 郁闷的C小加(二) (字符串处理)
题目链接 描述 聪明的你帮助C小加解决了中缀表达式到后缀表达式的转换(详情请参考"郁闷的C小加(一)"),C小加很高兴.但C小加是个爱思考的人,他又想通过这种方法计算一个表达式的值 ...
- nyoj-257 郁闷的C小加(一) 前缀表达式变后缀
郁闷的C小加(一) 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 我们熟悉的表达式如a+b.a+b*(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说 ...
- 郁闷的C小加(一)(后缀表达式)
郁闷的C小加(一) 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 我们熟悉的表达式如a+b.a+b*(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说 ...
- NYOJ-267 郁闷的C小加(二)
郁闷的C小加(二) 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 聪明的你帮助C小加解决了中缀表达式到后缀表达式的转换(详情请参考“郁闷的C小加(一)”),C小加很 ...
- nyoj 236 心急的C小加
心急的C小加 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 C小加有一些木棒,它们的长度和质量都已经知道,需要一个机器处理这些木棒,机器开启的时候需要耗费一个单位的 ...
随机推荐
- 移植 libevent-2.0.22-stable 到ARM平台
ARM 移植: 移植简单来讲就是使用ARM的编译环境,重新编译一份ARM平台上可以使用的库或执行文件,一般只需要重新制定C编译器和C++编译器即可. 特别注意的地方: 不能从windows解压文件后再 ...
- docker webapi
dockerfile FROM microsoft/aspnetcore:2.0 COPY . /docker1 WORKDIR /docker1 EXPOSE ENTRYPOINT ["d ...
- 如何在ubuntu下使用samba创建共享
快速简单的创建共享,比网上那些乱七八糟过时的文档强太多 原文地址: https://help.ubuntu.com/community/How%20to%20Create%20a%20Network% ...
- Codeforces Round #546 (Div. 2)D(贪心,思维,SET,VECTOR,模拟)
#include<bits/stdc++.h>using namespace std;int a[300007],b[500007],c[500007];set<int>st[ ...
- python 时间相关函数
python 中与时间处理相关的模块包括 time.datetime.以及 calendar time 模块 time() 函数:time() 函数用于返回当前时间的时间戳(1970年01月08时00 ...
- HDU6299-2018ACM暑假多校联合训练1002-Balanced Sequence
这个题的题意是给你n个字符串,认定()是一种平衡的串,两个以上连续的()()也是一种平衡的串,如果一对括号里面包含一个平衡的串,这个括号也被算在这个平衡的串之内, 如(()(()))是一个长度为8的平 ...
- CodeCraft-19 and Codeforces Round #537 (Div. 2) C. Creative Snap 分治
Thanos wants to destroy the avengers base, but he needs to destroy the avengers along with their bas ...
- 加载 xib 文件 UIView
记在 UIView 的 xib 文件方式有一下几种: 一 .直接加载 xib 文件, 没有.h.m 文件 1. NSBundle 方式 NSArray *objs = [[NSBundle mainB ...
- springcloud微服务总结 zuul
一 springcloud网关组件理解: 为什么需要网关呢? 我们知道我们要进入一个服务本身,很明显我们没有特别好的办法,直接输入IP地址+端口号,我们知道这样的做法很糟糕的,这样的做法大有问题,首先 ...
- nodejs npm包管理常用命令介绍
1.输入 npm config ls -l 可以查看当前的设置 2.针对某一项设置,可以通过下面方式: npm config set 属性名 属性值 eg:npm config set prefix ...