NYOJ 409 郁闷的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<string>
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<stack>
using namespace std;
char a[1009],b[1009],c[1009];
char pri[300];
char pri1[300];
//
void trans(char a[])///中缀转后缀
{
stack<char>q;///栈用来存储操作数
q.push('=');///用'='压栈,是为了与后来的操作符比较的时候,他的优先级最低
int j=0;
int k=0;
for(int i=0; a[i]!='='; i++)
{
if(a[i]>='0'&&a[i]<='9'||a[i]=='.')///可能有小数
{
b[j++]=a[i];
k++;
}
else
{
if(k!=0)
{
b[j++]=' ';
k=0;
}
if(a[i]=='(')
q.push(a[i]);
else if(a[i]==')')///一直出栈到'('
{
while(q.top()!='(')
{
b[j++]=q.top();
q.pop();
b[j++]=' ';
}
q.pop();
}
else
{
while(pri[a[i]]<=pri[q.top()])///将所有的运算符优先级比当前小的出来
{
b[j++]=q.top();
q.pop();
b[j++]=' ';
}
q.push(a[i]);///在将当前的运算符进栈
}
}
}
int nn=j-1;
if(b[nn]!=' ')
b[j++]=' ';
while(!q.empty()&&q.top()!='=')///栈中的元素也要全部输出
{
b[j++]=q.top();
q.pop();
b[j++]=' ';
}
b[j++]='=';
b[j]='\0';
puts(b);
}
void Trans(char a[])///中缀转前缀
{
stack<char>st;
int len=strlen(a);
int j=0;
int k=0;
for(int i=len-1; i>=0; i--)///逆着转换
{
if(a[i]>='0'&&a[i]<='9'||a[i]=='.')
{
c[j++]=a[i];
k++;
}
else
{
if(k!=0)
{
c[j++]=' ';
k=0;
}
if(a[i]==')')///与转后缀相反,')'直接进栈
{
st.push(a[i]);
}
else if(a[i]=='(')///'('的话要一直找到')'
{
while(st.top()!=')')
{
c[j++]=st.top();
st.pop();
c[j++]=' ';
}
st.pop();
}
else
{
while(!st.empty()&&pri1[st.top()]>pri1[a[i]])///将栈中的优先级比当前大的出栈
{
if(st.top()!='=')
{
c[j++]=st.top();
st.pop();
c[j++]=' ';
}
}
st.push(a[i]);
}
}
}
int hh=j-1;
if(c[hh]!=' ')
c[j++]=' ';
while(!st.empty()&&st.top()!='=')
{
c[j++]=st.top();
c[j++]=' ';
st.pop();
}
int nn=j-1;
if(c[nn]==' ')
nn=j-2;
else
nn=j-1;
for(int kk=nn;kk>=0;kk--)///最后也是要逆着输出来的
printf("%c",c[kk]);
printf(" =\n");
}
double JiSuan(char b[])
{
//puts(b);
char c[100];
memset(c,'\0',sizeof(c));
int j=0;
stack<double>st;
for(int i=0; b[i]!='='; i++)
{
if(b[i]>='0'&&b[i]<='9'||b[i]=='.')
c[j++]=b[i];
else
{
if(j!=0)
{
st.push(atof(c));///自动将字符转换为double
// cout<<"c "<<st.top()<<endl;
memset(c,'\0',sizeof(c));
j=0;
}
if(b[i]!=' ')
{
double n1;
double n2;
double n3;
switch(b[i])
{
case '+':
n1=st.top();
st.pop();
n2=st.top();
st.pop();
n3=n2+n1;
st.push(n3);
break;
case '-':
n1=st.top();
st.pop();
n2=st.top();
st.pop();
n3=n2-n1;
st.push(n3);
break;
case '*':
n1=st.top();
st.pop();
n2=st.top();
st.pop();
n3=n2*n1;
st.push(n3);
break;
case '/':
n1=st.top();
st.pop();
n2=st.top();
st.pop();
n3=n2/n1;
st.push(n3);
break;
}
}
}
}
return st.top();
}
int main()
{
int T;
pri['=']=-1;
pri['(']=0;
pri['+']=1;
pri['-']=1;
pri['*']=2;
pri['/']=2;
pri[')']=3;
pri1['=']=-1;
pri1[')']=0;
pri1['+']=1;
pri1['-']=1;
pri1['*']=2;
pri1['/']=2;
pri1['(']=3;
scanf("%d",&T);
for(int k=1; k<=T; k++)
{
memset(a,'\0',sizeof(a));
memset(b,'\0',sizeof(b));
memset(c,'\0',sizeof(c));
scanf(" %s",a);
// puts(a);
Trans(a);
trans(a);
/// puts(b);
printf("%.2lf\n",JiSuan(b));
}
return 0;
}
NYOJ 409 郁闷的C小加(三) (字符串处理)的更多相关文章
- nyoj 409——郁闷的C小加(三)——————【中缀式化前缀后缀并求值】
郁闷的C小加(三) 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 聪明的你帮助C小加解决了中缀表达式到后缀表达式的转换(详情请参考“郁闷的C小加(一)”),C小加很 ...
- NYOJ 267 郁闷的C小加(二) (字符串处理)
题目链接 描述 聪明的你帮助C小加解决了中缀表达式到后缀表达式的转换(详情请参考"郁闷的C小加(一)"),C小加很高兴.但C小加是个爱思考的人,他又想通过这种方法计算一个表达式的值 ...
- 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 257 郁闷的C小加(一) (字符串处理)
题目链接 描述 我们熟悉的表达式如a+b.a+b(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说)操作符在两个操作数中间:num1 operand num2.同理,后缀表达式就是操作符 ...
- NYOJ-267 郁闷的C小加(二)
郁闷的C小加(二) 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 聪明的你帮助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 236 心急的C小加
心急的C小加 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 C小加有一些木棒,它们的长度和质量都已经知道,需要一个机器处理这些木棒,机器开启的时候需要耗费一个单位的 ...
随机推荐
- 反向代理负载均衡-----nginx
一:集群 1.1:集群的概念 集群是一组相互独立的.通过高速网络互联的计算机,他们构成了一个组,并以单一系统的模式加以管理.一个客户与集群相互作用时,集群像是一个独立的服务器.集群配置是用于提高 ...
- [C/C++] 虚函数机制
转自:c++ 虚函数的实现机制:笔记 1.c++实现多态的方法 其实很多人都知道,虚函数在c++中的实现机制就是用虚表和虚指针,但是具体是怎样的呢?从more effecive c++其中一篇文章里面 ...
- 【bzoj5178】[Jsoi2011]棒棒糖 主席树
题目描述 Coffee的世界里也是有棒棒糖卖的,Coffee买了N(1≤N≤50000)只连着的.这N只棒棒糖包裹在小塑料袋中,排成一列,相邻的两只棒棒糖的塑料袋是接起来的.为了方便,我们把棒棒糖从左 ...
- Jmeter介绍+安装
JMeter介绍 JMeter 是Apache 基金会Jakarta 上的一个纯Java 开源项目,起初用于基于Web 的压力测试(pressure test),后来其应用范围逐渐扩展到对文件传输FT ...
- windows 网络共享无法用
可以远程电脑,但是无法网卡共享 原因是 远程电脑的Server服务停掉了,再开启下就行了
- [AT2363] [agc012_c] Tautonym Puzzle
题目链接 AtCoder:https://agc012.contest.atcoder.jp/tasks/agc012_c 洛谷:https://www.luogu.org/problemnew/sh ...
- TCP/IP协议详解---概述
工作之后,才发现以前在学校里学的东西忘得太快太干净了,现在需要一点点地捡起来了,要不然写几行程序会闹很多笑话会出现很多bug的.从今天开始,翻一翻<TCP/IP协议详解 卷1>这本 ...
- 洛谷P3933 Chtholly Nota Seniorious 【二分 + 贪心 + 矩阵旋转】
威廉需要调整圣剑的状态,因此他将瑟尼欧尼斯拆分护符,组成了一个nnn行mmm列的矩阵. 每一个护符都有自己的魔力值.现在为了测试圣剑,你需要将这些护符分成 A,B两部分. 要求如下: 圣剑的所有护符, ...
- 洛谷 P2233 [HNOI2002]公交车路线 解题报告
P2233 [HNOI2002]公交车路线 题目背景 在长沙城新建的环城公路上一共有8个公交站,分别为A.B.C.D.E.F.G.H.公共汽车只能够在相邻的两个公交站之间运行,因此你从某一个公交站到另 ...
- https的通信过程
https的特点 1. https有 握手阶段 和 请求阶段2. 握手阶段 使用 非对称加密算法 请求阶段 使用 对称加密算法3. 保证数据的完整性使用数字签名4. 握手阶段有两组非对称加密,数字证书 ...