PTA-后缀表达式求值

PTA-后缀表达式求值

前言

后缀表达式,又称逆波兰式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行。
运用后缀表达式进行计算的具体做法:
建立一个操作数栈S。然后从左到右读表达式,如果读到操作数就将它压入栈S中,如果读到n元运算符(即需要参数个数为n的运算符)则取出由栈顶向下的n项操作数进行运算,再将运算的结果代替原栈顶的n项压入栈中。重复上面过程,如果后缀表达式读完且栈中只剩一个操作数,则该数就是运算结果;如果后缀表达式读完但是栈中操作数多于一个,则后缀表达式错误;如果栈中操作数只剩一个,但是后缀表达式还未读完且当前运算符为双元操作符,则后缀表达式同样错误。


提示:以下是本篇文章正文内容

输入格式:

在一行中输入一个以#号结束的非空后缀式,#不属于表达式的一部分,操作数和运算符都以空格分隔,运算数为绝对值不超过100的整数,运算符仅有+、-、*、/ 四种。

输出格式:

1. 输出后缀式计算结果,所有的计算都只取结果的整数部分。题目保证计算的中间和最后结果的绝对值都不超过10
​9 。
2. 如果执行除法时出现分母为零的非法操作,则在一行中输出:Error: X/0,X是当时的分子。
3. 如果后缀表达式中运算符多了或者少了,则在一行中输出:Expression Error: X,X是当时栈顶元素。

输入样例1:
5 -2 + 3 * #
输出样例1::
9
输入样例2:
5 -2 2 + / #
输出样例2:
Error: 5/0
输入样例3:
5 -1 3 + / - * #
输出样例3:
Expression Error: 2

思路:

因为此题我们主要需要解决的问题是后缀表达式求值及逆波兰式,而后缀表达式的求值过程为:

  1. 如果遇到数字就进栈;
  2. 如果遇到操作符,就从栈顶弹出两个数字分别为 num2(栈顶)、num1(栈中的第二个元素);计算 num1 运算符 num2 的值,然后将所求的结果再次push入栈
  3. 逆波兰表达式是的代码实现很方便,用一个栈就能解决。
  4. 注意:栈的弹出顺序和入栈顺序正好相反。

示例代码(java):

package pta;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Scanner;

public class 后缀表达式求值 {
    public static void main(String[] args)throws Exception {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        String num[] = str.split(" ");
        Deque<Integer> de = new ArrayDeque<>();
        int a = 0;
        int b = 0;
        //for(String s : num)
//		for (int i = 0; i < num.length-1; i++) {
//			System.out.println(num[i]);
//		}
        u:
        for(int i = 0;i<num.length-1;i++)
        {
            String s = num[i];
            switch (s) {
                case "+":
                    try {
                        a = de.pop();
                        b = de.pop();
                        de.push(a+b);
                        break;
                    } catch (Exception e) {
                        System.out.print("Expression Error: "+a);
                        break u;
                    }

                case "-":
                    try {
                        a = de.pop();
                        b = de.pop();
                        de.push(b-a);	//注意a和b的运算顺序
                        break;
                    }  catch (Exception e) {
                        System.out.print("Expression Error: "+a);
                        break u;
                    }

                case "*":
                    try {
                        a = de.pop();
                        b = de.pop();
                        de.push(a*b);
                        break;
                    } catch (Exception e) {
                        System.out.print("Expression Error: "+a);
                        break u;
                    }

                case "/":
                    try {
                        a = de.pop();
                        b = de.pop();
                        //判断分母是否为0
                        if(a==0) {
                            System.out.print("Error: "+b+"/0");
                            break u;
                        }
                        de.push(b/a);	//注意a和b的运算顺序
                        break;
                    }  catch (Exception e) {
                        System.out.print("Expression Error: "+a);
                        break u;
                    }

                default:
                    de.push(Integer.parseInt(s));
            }
        }
        if(de.size()>1) {
            System.out.println("Expression Error: "+de.pop());
        }else if(de.size()==1) {
            System.out.print(de.pop());
        }
    }

}

总结

在此题中为了满足题目要求,用到了try…catch…来预处理错误,实在是没有想到其他的解决方法,若有更好的思路,欢迎大佬们指出。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值