您的位置:首页 > 其它

nyoj 题目409 郁闷的C小加(三)

2016-08-21 17:25 190 查看

                                                               郁闷的C小加(三)

时间限制:1000 ms  |            内存限制:65535 KB
难度:4

描述 聪明的你帮助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

上传者苗栋栋解法:

前缀表达式:

(1) 初始化一个栈:运算符栈pq和两个个字符串str(反向字符串),tmp(前缀表达式);

(2) 将中缀表达式反向,遍历字符串;

(3) 遇到操作数时,加到存储前缀表达的字符串中;

(4) 遇到运算符时,比较其与pq栈顶运算符的优先级:

(4-1) 如果pq.top()=‘#’,或栈顶运算符为右括号“(”,则直接将此运算符入栈;

(4-2) 否则,若优先级比栈顶运算符的较高或相等,也将运算符压入pq;

(4-3) 否则,将pq栈顶的运算符弹出并加入tmp中,再次转到(4-1)与pq中新的栈顶运算符相比较;

(5) 遇到括号时:

(5-1) 如果是右括号“(”,则直接压入pq;

(5-2) 如果是左括号“)”,则依次弹出pq栈顶的运算符,并加到tmp中,直到遇到右括号为止,此时将这一对括号丢弃;

(6) 重复步骤(2)至(5),直到表达式的最右边;

(7) 将pq中剩余的运算符依次弹出并加到tmp中;

(8) 输出tmp,结果即为中缀表达式对应的前缀表达式。

后缀表达式:

同上!

不同的是不需要将中缀表达式反向,还有最关键的是(4-2)步: 否则,若优先级比栈顶运算符的较高,也将运算符压入pq;

(4-3) 否则,将pq栈顶的运算符弹出并加入tmp中,再次转到(4-1)与pq中新的栈顶运算符相比较;

然后就可以算出后缀表达式了!

#include<bits/stdc++.h>
using namespace std;
int flag;
string str;
int cmp(char ch)
{
switch(ch)
{
case '+':
case '-':return 1;
case '*':
case '/':return 2;
default:return 0;
}
}
void revers(string ss)
{
int len=ss.size();
for(int i=len-2;i>=0;i--)
{
if(ss[i]==')')
str+='(';
else if(ss[i]=='(')
str+=')';
else
str+=ss[i];
}
str+='=';
}
int change(string st)
{
int i=0,len=st.size();
string tmp;
stack<char>pq;
pq.push('#');
while(i<len-1)
{
if(st[i]=='(')
{
pq.push(st[i]);
i++;
}
else if(st[i]==')')
{
while(pq.top()!='(')
{
tmp+=pq.top();
pq.pop();
tmp+=' ';
}
pq.pop();
i++;
}
else if(st[i]=='+'||st[i]=='-'||st[i]=='*'||st[i]=='/')
{
if(flag==0)
{
while(cmp(pq.top())>cmp(st[i]))
{
tmp+=pq.top();
tmp+=' ';
pq.pop();
}
pq.push(st[i]);
i++;
}
else
{
while(cmp(pq.top())>=cmp(st[i]))
{
tmp+=pq.top();
tmp+=' ';
pq.pop();
}
pq.push(st[i]);
i++;
}
}
else
{
while(st[i]>='0'&&st[i]<='9'||st[i]=='.')
{
tmp+=st[i];
i++;
}
tmp+=' ';
}
}
while(pq.top()!='#')
{
tmp+=pq.top();
pq.pop();
tmp+=' ';
}
if(flag==0)
{
tmp.erase(tmp.size()-1,1);
reverse(tmp.begin(),tmp.end());
tmp+=" =";
cout<<tmp<<"\n";
}
else
{
string str1=tmp,buf;
char a[100005];
tmp+='=';
cout<<tmp<<"\n";
stack<double>qp;
stringstream ss(str1);
while(ss>>buf)
{
if(isdigit(buf[0]))
{
int i;
double num;
for(i=0;i<buf.size();i++)
a[i]=buf[i];
a[i]='\0';
num=atof(a);
qp.push(num);
}
else
{
double x=qp.top();
qp.pop();
double y=qp.top();
qp.pop();
if(buf=="+")
qp.push(x+y);
else if(buf=="-")
qp.push(y-x);
else if(buf=="*")
qp.push(x*y);
else
qp.push(y/x);
}
}
printf("%.2lf\n",qp.top());
}
flag=1;
}
int main()
{
int T;
cin>>T;
while(T--)
{
flag=0;
str.clear();
string s;
cin>>s;
revers(s);
change(str);
change(s);
}
return 0;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: