中缀表达式转后缀表达式并求值

RT。题目链接: http://zju.acmclub.com/index.php?app=problem_title&id=1&problem_id=1743

求一表达式的值。需要注意的有以下几个方面:

1.首先想到的是先将中缀表达式转成后缀表达式,再扫描后缀表达式这一方法。扫描后缀表达式时,每遇到操作数时压栈,遇到操作符时从栈顶弹出2个操作数计算并压栈。最后返回栈顶即为结果。当然,题目中给的是算符优先法规定操作符之间的优先级。也可用其他的方式规定优先级。比如我的方法是事先规定好栈内优先级和栈外优先级。

2.其次,在转化后缀表达式的过程中,最好使用c++的泛型。因为如果用int型的数组来存储后缀式的话,操作符均变成ascii码来存储,有可能与操作数混淆。我的方法是操作符的ascii码减48(即操作符在后缀表达式中以负数形式出现,为了与操作数区分开)后再存储到数组中。另外,如果用char型数组来存后缀式的话,类似1234的多位操作数无法支持。

代码:

#include<iostream>
#include<cstring>
#define SIZE 100
using namespace std;
int main()
{
    int isp[50];
    int icp[50];
    isp['#'] = 0;
    isp['('] = 1;
    isp['*']= isp['/'] = 5;
    isp['+']= isp['-'] = 3 ;
    isp[')'] = 6;
    icp['#'] = 0;
    icp['('] = 6;
    icp['*']= icp['/'] = 4;
    icp['+']= icp['-'] = 2 ;
    icp[')'] = 1;//规定栈内优先级和栈外优先级

    char str[SIZE];//存储输入字符串
    int num_stack[SIZE];//计算后缀表达式时使用的栈
    char op_stack[SIZE];//中缀表达式转后缀表达式时使用的栈
    int top_num;
    int top_op;
    int i,j,k,sum;
    int num[SIZE];
    char buf;
    int temp1,temp2;
    while(cin>>str)
    {

        top_op = -1;
        op_stack[++top_op] = '#';//操作符栈
        j = 0;
        for(i=0; i<strlen(str); i++)
        {
            if(str[i] <= '9' && str[i] >= '0')
            {
                sum = str[i] - '0';//操作数最高位先赋给sum
                while(str[i+1] <= '9' && str[i+1] >= '0')
                {
                    sum = sum * 10 + (str[i+1] - '0' );
                    i++;
                }
                //cout<<"sum="<<sum<<endl;
                //num_stack[++top_num] = sum;//操作数直接进栈
                num[j++] = sum ;
            }

            else//如果是操作符,则弹出栈顶元素比较优先级
            {
                //cout<<"top_op="<<top_op<<endl;
                while(top_op > -1)
                {
                    buf = op_stack[top_op];//返回操作符栈顶并比较
                    if(isp[buf] < icp[str[i]])
                    {
                        op_stack[++top_op] = str[i];    //进栈
                        break;
                    }
                    else if(isp[buf] > icp[str[i]])
                    {
                        num[j++] = op_stack[top_op--] - 48;//退栈并输出操作符

                    }
                    else //相等时直接退栈,也不要忘了break
                    {
                        top_op--;
                        break;
                    }


                }


            }

        }
        //扫描后缀表达式并输出
        top_num = -1;//初始化数字栈,数字栈现在还没有使用
        temp1 = temp2 = 0;
        for(k=0; k<j; k++)
        {
            if(num[k]!=-1 && num[k]!=-3 && num[k]!=-5 && num[k]!=-6)
                num_stack[++top_num] = num[k];//操作数入栈
            else if (num[k] == -1)//匹配到除号
            {
              temp1 = num_stack[top_num--];
              temp2 = num_stack[top_num--];
              num_stack[++top_num] = temp2 / temp1;
            }
            else if (num[k] == -3)//匹配到减号
            {
              temp1 = num_stack[top_num--];
              temp2 = num_stack[top_num--];
              num_stack[++top_num] = temp2 - temp1;
            }
            else if (num[k] == -5)//匹配到加号
            {
              temp1 = num_stack[top_num--];
              temp2 = num_stack[top_num--];
              num_stack[++top_num] = temp2 + temp1;
            }
            else if (num[k] == -6)//匹配到乘号
            {
              temp1 = num_stack[top_num--];
              temp2 = num_stack[top_num--];
              num_stack[++top_num] = temp2 * temp1;
            }
        }
        cout<<num_stack[top_num];//最后输出当前栈顶即可
        cout<<endl;
    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值