郁闷的C小加(二)
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
4
-
描述
-
聪明的你帮助C小加解决了中缀表达式到后缀表达式的转换(详情请参考“郁闷的C小加(一)”),C小加很高兴。但C小加是个爱思考的人,他又想通过这种方法计算一个表达式的值。即先把表达式转换为后缀表达式,再求值。这时又要考虑操作数是小数和多位数的情况。
-
输入
-
第一行输入一个整数T,共有T组测试数据(T<10)。
每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以“=”结束。这个表达式里只包含+-*/与小括号这几种符号。其中小括号可以嵌套使用。数据保证输入的操作数中不会出现负数并且小于1000000。
数据保证除数不会为0。
输出
- 对于每组测试数据输出结果包括两行,先输出转换后的后缀表达式,再输出计算结果,结果保留两位小数。两组测试数据之间用一个空行隔开。 样例输入
-
21+2=(19+21)*3-4/5=
样例输出
-
12+=3.001921+3*45/-=119.20
来源
- 改编自NYOJ 上传者
这道题真的是……唉,一把辛酸泪,没爱了,用的队列,看的别人的代码用的队列,但是一直程序有错误,然后忽略了数组的循环直接将i加了,但是队列得出队列
#include<stdio.h>
#include<string.h>
#include<stack>
#include<queue>
#include<ctype.h>
#include<stdlib.h>
using namespace std;
char str[1010];
stack<char>s;//定义一个栈存操作符
queue<char>q;//定义一个队列存转化后的后缀表达式
int priority(char ch){
switch(ch){
case '+':
case '-':
return 1;
break;
case '*':
case '/':
return 2;
break;
case '(':return 0;
default:return -1;
}
}
int trans(){
while(!s.empty())
s.pop();
while(!q.empty())
q.pop();
s.push('=');
int len=strlen(str);
for(int i=0;str[i]!='=';i++){
if(str[i]>='0'&&str[i]<='9'||str[i]=='.'){
q.push(str[i]);
}
else{
q.push('#');//将连着的多个操作数分隔开
if(str[i]=='(')
s.push(str[i]);
else if(str[i]==')'){
while(s.top()!='('){
q.push(s.top());
s.pop();
}
s.pop();//最后将左括号出栈(输出中不需要括号输出)
}
else{
while(priority(str[i])<=priority(s.top())){
q.push(s.top());
s.pop();
}
s.push(str[i]);//等到栈中的元素的优先级小于当前要入栈元素的时候,将元素入栈
}
}
}
while(s.top()!='='){
q.push(s.top());
s.pop();
}
q.push('=');
return 0;//这里记得return
}
double Calculate(){//计算(Node:这里的每一步都要出队列)
char zs[1010];//转换字符数组,需要存储带小数点的数的字符
stack<double>num;//定义一个栈存储操作数
int k=0;
int flag=0;
while(q.front()!='='){
if(q.front()>='0'&&q.front()<='9'||q.front()=='.'){
zs[k++]=q.front();
q.pop();
flag=1;
}
else{
if(flag){
zs[k]='\0';
num.push(atof(zs));
k=0;
flag=0;
}
else if(q.front()=='#'){//这个必须得判断,而且需要出队列,否则会循环不完的
q.pop();
continue;
}
else if(q.front()!='#'){//为加减乘除
double num1=num.top();
num.pop();
double num2=num.top();
num.pop();
switch(q.front()){
case '+':
num.push(num2+num1);
q.pop();
break;
case '-':
num.push(num2-num1);
q.pop();
break;
case '*':
num.push(num2*num1);
q.pop();
break;
case '/':
num.push(num2/num1);
q.pop();
break;
}
}
}
}
return num.top();
}
int main(){
int T;
char str2[1010];
scanf("%d",&T);
while(T--){
scanf("%s",str);
trans();
int t=0;
while(!q.empty()){
str2[t++]=q.front();
q.pop();
if(str2[t-1]!='#')
printf("%c",str2[t-1]);
}
printf("\n");
for(int i=0;i<t;i++){
q.push(str2[i]);
}
printf("%.2f\n",Calculate());
}
return 0;
}
本文介绍了一个算法,用于将包含小数和多位数的中缀表达式转换为后缀表达式,并计算其值。文章提供了完整的C++实现代码,包括栈和队列的使用,以及如何处理括号嵌套等问题。
591

被折叠的 条评论
为什么被折叠?



