题目描述:
聪明的你帮助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<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<math.h>
#include<stack>
#include<ctype.h>
#include<stdlib.h>
#include<map>
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
int ju(char c)//定义运算符优先级
{
switch(c)
{
case '=':
return 0;
case ')':
return 0;
case '+':
return 1;
case '-':
return 1;
case '*':
return 2;
case '/':
return 2;
default:
return -1;
}
}
void com(stack<double>& num,stack<char>& ch)//计算表达式
{
double b=num.top();
num.pop();
double a=num.top();
num.pop();
switch(ch.top())
{
case '+':
num.push(a+b);
break;
case '-':
num.push(a-b);
break;
case '*':
num.push(a*b);
break;
case '/':
num.push(a/b);
break;
}
ch.pop();
}
int main()
{
int i,j,T,l;
char s[1200];
scanf("%d",&T);
queue<char>q;
stack<char>p;
stack<char>ch;
stack<double>num;
while(T--)
{
while(!num.empty())
num.pop();
while(!ch.empty())
ch.pop();
while(!q.empty())
q.pop();
while(!p.empty())
p.pop();
scanf("%s",s);
l=strlen(s);
for(i=0; i<l; i++)//计算表达式结果
{
if(isdigit(s[i]))
{
double n=atof(&s[i]);
while(i<l&&s[i]=='.'||isdigit(s[i]))
i++;
i--;
num.push(n);
}
else if(s[i]=='(')
ch.push(s[i]);
else if(s[i]==')')
{
while(ch.top()!='(')
com(num,ch);
ch.pop();
}
else if(ch.empty()||ju(s[i])>ju(ch.top()))
ch.push(s[i]);
else
{
while(!ch.empty()&&ju(s[i])<=ju(ch.top()))
com(num,ch);
ch.push(s[i]);
}
}
ch.pop();
ch.push('#');
for(i=0; i<l; i++)//转换为后缀表达式
{
if(isdigit(s[i]))
{
while(i<l&&s[i]=='.'||isdigit(s[i]))
{
q.push(s[i]);
i++;
}
q.push(' ');
i--;
}
else if(s[i]=='(')
ch.push(s[i]);
else if(s[i]==')')
{
while(ch.top()!='(')
{
q.push(ch.top());
q.push(' ');
ch.pop();
}
ch.pop();
}
else if(s[i]=='-'||s[i]=='+'||s[i]=='*'||s[i]=='/')
{
while(ju(s[i])<=ju(ch.top()))
{
q.push(ch.top());
q.push(' ');
ch.pop();
}
ch.push(s[i]);
}
}
while(!ch.empty())
{
q.push(ch.top());
q.push(' ');
ch.pop();
}
for(i=l-1; i>=0; i--)//转换为前缀表达式
{
if(isdigit(s[i]))
{
while(i>=0&&isdigit(s[i])||s[i]=='.')
{
p.push(s[i]);
i--;
}
p.push(' ');
i++;
}
else if(s[i]==')')
ch.push(s[i]);
else if(s[i]=='(')
{
while(ch.top()!=')')
{
p.push(ch.top());
p.push(' ');
ch.pop();
}
ch.pop();
}
else if(ch.empty()||ju(s[i])>=ju(ch.top()))
ch.push(s[i]);
else
{
while(!ch.empty()&&ju(s[i])<ju(ch.top()))
{
p.push(ch.top());
p.push(' ');
ch.pop();
}
ch.push(s[i]);
}
}
while(!ch.empty())
{
p.push(ch.top());
p.push(' ');
ch.pop();
}
p.pop();
while(!p.empty())
{
if(p.top()=='=')
{
p.pop();
p.pop();
continue;
}
printf("%c",p.top());
p.pop();
}
printf(" =\n");
while(q.front()!='#')
{
printf("%c",q.front());
q.pop();
}
printf("=\n");
printf("%.2lf\n",num.top());
}
}