NYOJ409 郁闷的c小加三

传送门: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;
}



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值