后缀表达式求值

后缀表达式求值

时间限制: 1 Sec
内存限制: 128 MB

题目描述

为了便于处理表达式,常常将普通表达式(称为中缀表示)转换为后缀{运算符在后,如X/Y写为XY/表达式。在这样的表示中可以不用括号即可确定求值的顺序,如:(P+Q)(R-S) → PQ+RS-。后缀表达式的处理过程如下:扫描后缀表达式,凡遇操作数则将之压进堆栈,遇运算符则从堆栈中弹出两个操作数进行该运算,将运算结果压栈,然后继续扫描,直到后缀表达式被扫描完毕为止,此时栈底元素即为该后缀表达式的值。

输入

输入一行表示后缀表达式,数与数之间一定有空格隔开(可能不只一个空格),最后输入@表示输入结束。
数据保证每一步的计算结果均为不超过100000的整数。

输出

输出一个整数,表示该表达式的值.

样例输入

14  3 20 5 / * 8 - + @

样例输出

18

解题思路:

以字符的形式输入,存储在字符数组中(用 fgets 才能在字符数组中存储空格),遍历数组,遇到数字(注意字符与数字的转换)就入栈,遇到运算符就从栈中弹出两个数字进行运算,将运算结果入栈。直到运算到栈中只剩一个元素就是结果。

AC代码

#include<bits/stdc++.h> //万能头文件

using namespace std;

int is_num(char a);  //判断是数字
int is_op_char(char a); //判断是运算符
int calculate(int i,int j,char c); //进行运算操作

int main(void)
{
    stack<int>nums;
    char c[300];
    fgets(c,sizeof(c),stdin); //fgets能够读入空格,但gets不能读入空格。stdin表示从屏幕输入
    int n = strlen(c);  //下面循环最好不要i < strlen(c),因为每次strlen都要循环一边数组
    int i,j;

    for(i = 0; i < n ; ++i)
    {
        if(c[i] == '@')
            break;    //遇到@终止
        if(is_num(c[i]))
        {
            int num = c[i]-'0';
            for(j = i+1; is_num(c[j]) ; ++j)  //当第i个是数字时,要往后找,直到不是数字的一个字符
            {
                num = num*10+(c[j]-'0');   //计算当前的数字
            }
            i = j;    //找到数字之后要更新 i 的位置
            nums.push(num);  //将数字入栈
        }

        if(is_op_char(c[i])) //遇到运算符时,将栈顶的两个元素弹出进行运算
        {
            int a = nums.top();
            nums.pop();
            int b = nums.top();
            nums.pop();
            //  cout<<b<<c[i]<<a<<'='<<op(b,a,c[i])<<endl;
            nums.push( calculate( b, a,c[i] ) );
        }
    }

    int ans = nums.top(); //判断栈中只剩一个元素(防止不正规输入)
    nums.pop();
    if(nums.empty())
        cout << ans ;

    return 0;
}
int is_num(char a)
{
    if((a) >= '0' && (a) <= '9')
        return 1;
    return 0;
}

int is_op_char(char a)
{
    if(((a) == '+') ||((a) == '-') ||((a) == '*') ||((a) == '/'))
        return 1;
    return 0;
}

int calculate(int a,int b,char op)
{
    switch(op)
    {
    case'+':
        return (a+b);
    case'-':
        return (a-b);
    case'*':
        return (a*b);
    case'/':
        return (a/b);
    }
}


运行结果

在这里插入图片描述

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值