第九届河南省程序设计大赛 A表达式求值

第九届河南省程序设计大赛




A 表达式求值


内存限制:64MB  时间限制:1s  Special Judge: No

题目描述:

假设表达式定义为: 1. 一个十进制的正整数 X 是一个表达式。 2. 如果 X 和 Y 是 表达式,则 X+Y, X*Y 也是表达式; *优先级高于+. 3. 如果 X 和 Y 是 表达式,则 函数 Smax(X,Y)也是表达式,其值为:先分别求出 X ,Y 值的各位数字之和,再从中选最大数。 4.如果 X 是 表达式,则 (X)也是表达式。 例如: 表达式 12*(2+3)+Smax(333,220+280) 的值为 69。 请你编程,对给定的表达式,输出其值。  

输入描述:

【标准输入】 第一行: T 表示要计算的表达式个数 (1≤ T ≤ 10) 接下来有 T 行, 每行是一个字符串,表示待求的表达式,长度<=1000 

输出描述:

【标准输出】 对于每个表达式,输出一行,表示对应表达式的值。

样例输入:

复制
3
12+2*3
12*(2+3)
12*(2+3)+Smax(333,220+280)

样例输出:

18
60
69

这道题是我的心病啊,之前看到别人写的关于这道题的题解都是说要用到中缀转后缀(逆波兰式)

因为我对逆波兰式不太熟悉所以想着还是按照中缀来写,遇到Smax函数时直接跳过,通过函数中的逗号来判断是不是这个函数

想法是对的,样例也是对的,但就是算不对,老是出现运行时错误,但又想不出来反例,

终于今天让我注意到了,我建的两个用来存放运算符的栈出了问题,尤其是用来储存运算结果的是sta1,因为有的时候可能需要连续抛出两个数进行对应的运算,但是此时sta1可能只有一个数,所以就会出现运行时错误,

妈呀,如果不改过来我可能以后就对表达时产生抵触了大笑

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<cmath>
using namespace std;
int a1[8][8]={
        {0,0,0,0,0,0,0,0},
        {0,1,0,1,0,1,1,0},
        {0,1,1,1,0,1,1,1},
        {0,0,0,1,0,1,0,0},
        {0,0,0,0,1,1,0,0},
        {0,1,1,1,1,1,1,1},
        {0,1,0,1,0,1,1,0},
        {0,1,1,1,0,1,1,1},
    };
int sw(int x,int y)//求两个多位数数为相加的结果,并返回较大的值
{
    int n1=0,n2=0;
    while(x!=0)
    {
        n1+=x%10;
        x/=10;
    }
    while(y!=0)
    {
        n2+=y%10;
        y/=10;
    }
    n1=n1>n2?n1:n2;
    return n1;
}
int bj(char a,char b)//判断算符优先顺序
{
    int i=0,j=0;
    if(a=='+')i=1;if(a=='*')i=2;if(a==',')i=3;if(a=='(')i=4;if(a==')')i=5;if(a=='-')i=6;if(a=='/')i=7;
    if(b=='+')j=1;if(b=='*')j=2;if(b==',')j=3;if(b=='(')j=4;if(b==')')j=5;if(b=='-')j=6;if(b=='/')j=7;
    return a1[i][j];
}
int main()
{
    int k;
    stack<int>sta1;
    stack<char>sta2;
    char str1[1090];
    cin>>k;
    sta2.push('#');
    sta1.push(-99999999);
    while(k--)
    {
        cin>>str1;
        int len1=strlen(str1);
        int n1=0;
        for(int i=0;i<len1;i++){
            if(str1[i]<='9'&&str1[i]>='0')//添加数字时,可能是一个多位数,所以要
            {
                int n2=str1[i]-'0';
                i++;
                while(str1[i]>='0'&&str1[i]<='9'&&i<len1)
                {
                    n2=n2*10+str1[i]-'0';
                    i++;
                }
                sta1.push(n2);
                if(i>=len1)
                    break;
            }
            if((str1[i]<'0'||str1[i]>'9')&&sta2.top()=='#')//添加第一个算符
                sta2.push(str1[i]);
            else if(str1[i]=='(')//若是(,则直接插入栈
            {
                sta2.push(str1[i]);
                continue;
            }
            else if(str1[i]=='S')//若是Smax,则直接跳过,使用,来表示
            {
                i=i+3;
                continue;
            }
            else if(bj(sta2.top(),str1[i])&&sta2.top()!='#'){//若栈顶算符优先,则进行相对应操作
                int k1=sta1.top();sta1.pop();
                if(sta1.top()==-99999999)break;
                int k2=sta1.top();sta1.pop();
                if(sta2.top()=='*'){
                    k1=k1*k2;
                    sta1.push(k1);
                }
                if(sta2.top()=='+'){
                    k1=k1+k2;
                    sta1.push(k1);
                }
                if(sta2.top()=='-'){
                    k1=k2-k1;
                    sta1.push(k1);
                }
                if(sta2.top()=='/'){
                    k1=k2/k1;
                    sta1.push(k1);
                }
                if(sta2.top()==','){
                    k1=sw(k1,k2);
                    sta1.push(k1);
                }
                sta2.pop();//栈顶算符已使用完毕,应出栈;

                if(str1[i]==',')//若是,则直接插入;
                {
                    sta2.push(str1[i]);
                    continue;
                }
                if(str1[i]!=')'){
                    sta2.push(str1[i]);
                }
                else {
                    if(sta2.top()=='#')break;
                    if(sta2.top()=='(')sta2.pop();
                    else i=i-1;//若输入的算符为),但栈顶并不是(,则重复一次
                }
            }
            else if(!bj(sta2.top(),str1[i])){
                sta2.push(str1[i]);
            }
        }
        while(sta2.top()!='#'&&sta1.top()!=-99999999)//此时将sta2中的算符进行完
        {
            int k3=sta1.top();sta1.pop();
            if(sta1.top()==-99999999){sta1.push(k3);break;}
            int k4=sta1.top();sta1.pop();
            if(sta2.top()=='+')k3=k3+k4;
            if(sta2.top()=='*')k3=k3*k4;
            if(sta2.top()=='-')k3=k4-k3;
            if(sta2.top()=='/')k3=k4/k3;
            sta1.push(k3);
            sta2.pop();
        }
        cout<<sta1.top()<<endl;
        sta1.pop();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40788630/article/details/80389659
今日推荐