传送门:http://acm.nyist.net/JudgeOnline/problem.php?pid=409
NYOJ郁闷的c小加一、二、三都是关于表达式转换及求值的,主要涉及栈知识点。郁闷的c小加三是在二的基础上多了个前缀表达式,因此可以稍作修改把一二A掉。
这道题就是将表达式转换成前缀和后缀表达式,并输出计算结果,因此可以定义一个result结构体,string型的s1、s2以及double型的res。
其中s1保存前缀结果,s2所保存后缀结果,res保存计算结果。
代码如下:
#include <iostream>
#include<ctype.h>
#include<string>
#include<cstdlib>
#include<stack>
#include<iomanip>
#define bug cout<<"bug"<<endl;
using namespace std;
struct result
{
string s1;//保存前缀结果
string s2;//保存后缀结果
double res;
};
char str[1005];
stack<result>da;
stack<char>op;
int rank(char c)//判断优先级
{
switch (c)
{
case '+':return 1;
case '-':return 1;
case '*':return 2;
case '/':return 2;
case '(':return 3;
case ')':return 0;
case '=':return -1;
case '#':return -2;
}
return 0;
}
double compute(double x,char o,double y)//计算表达式结果
{
switch(o)
{
case '+':
return x+y;
case '-':
return x-y;
case '*':
return x*y;
case '/':
return x/y;
default :
return x;
}
return 0.0;
}
result calculate(result r1,char o,result r2)
{
char buf1[5]={o,' ','\0'},buf2[5]={' ',o,' ','\0'};
string t=buf1;
//前缀表达式处理
t.append(r1.s1);
t.append(" ");
r1.s1=t.append(r2.s1);
//后缀表达式处理
r1.s2.append(" ");
r1.s2.append(r2.s2);
r1.s2.append(buf2);
//计算结果
r1.res=compute(r1.res,o,r2.res);
return r1;
}
void ac()
{
int i=0,j,k;
char buf[10];
result r;
op.push('#');
while(op.top()!='=')
{
if(isdigit(str[i]))
{
k=0;
for(j=i;isdigit(str[j])||str[j]=='.';j++)
buf[k++]=str[j];
buf[k]='\0';
r.s1=r.s2=buf;
r.res=atof(buf);
da.push(r);
i=j;
}
if(!isdigit(str[i]))
{
if(op.top()=='('&&str[i]==')')
{
op.pop();
i++;
}
else if(rank(str[i])>rank(op.top())||(op.top()=='('))
{
op.push(str[i]);
i++;
}
else
{
result t=da.top();
da.pop();
t=calculate(da.top(),op.top(),t);
op.pop();
da.pop();
da.push(t);
}
}
}
while(!op.empty())
op.pop();
}
int main()
{
int ncase;
cin>>ncase;
while(ncase--)
{
cin>>str;
ac();
cout<<da.top().s1<<" ="<<endl<<da.top().s2<<"="<<endl<<setprecision(2)<<fixed<<da.top().res<<endl;
da.pop();
}
return 0;
}