计算逆波兰表达式(后缀表达式)Java版

后缀表达式是什么?

后缀表达式也是逆波兰表达式,而波兰表达式就是前缀表达式。

一个表达式E的后缀形式可以如下定义:

(1)如果E是一个变量或常量,则E的后缀式是E本身。

(2)如果E是E1 op E2形式的表达式,这里op是任何二元操作符,则E的后缀式为E1'E2' op,这里E1'和E2'分别为E1和E2的后缀式。

(3)如果E是(E1)形式的表达式,则E1的后缀式就是E的后缀式。

如:我们平时写a+b,这是中缀表达式,写成后缀表达式就是:ab+

(a+b)*c-(a+b)/e的后缀表达式为:

(a+b)*c-(a+b)/e

→((a+b)*c)((a+b)/e)-

→((a+b)c*)((a+b)e/)-

→(ab+c*)(ab+e/)-

→ab+c*ab+e/-

直接用明确的表达式可能更好理解如:

4 * 5 - 8 + 60 + 8 / 2(中缀)  => 4 5 * 8 - 60 + 8 2 / +(后缀)

因为中缀表达式是人们常用的表达式,对应人来说很方便,但是对应计算机来说处理起来比较复杂

所以我们需要将中缀表达式转换成后缀表达式。

带括号的中缀表达式转换成后缀表达式后是没有括号存在的。

思路分析:

1、创建一个栈

2、循环扫描后缀表达式

3、当扫描到的是数字时,直接压入栈中

4、当扫描到运算符时,从栈中取出栈顶元素和次顶元素与该运算符进行计算

        4.1、如果运算符是➖或者➗要用栈中的次顶元素➖(➗)栈顶元素

5、将计算结果再压入栈中

6、重复3~5步,直到扫描完整个表达式,最后栈中的一个元素就是表达式的最终结果。

代码实现:

public class PolandNotation {

    public static void main(String[] args) {
        //定义一个逆波兰表达式
        // (3+4)*50-6 => 3 4 + 50 * 6 -
        // 4.8*5.5-8+60+8/2 => 4.8 5.5 * 8 - 60 + 8 2 / +
        // 为了方便,逆波兰表达式的数字和符号用一个空格隔开
        String suffixExpression = "4.8 5.5 * 8 - 60 + 8 2 / +";

        //将表达式存储在ArrayList中
        List<String> list;
        list = getListString(suffixExpression);
        System.out.println(list);

        //调用方法计算逆波兰表达式
        System.out.printf("表达式%s = %f", suffixExpression, lastPolandExpression(list));
    }

    //判断是不是运算符
    public static boolean isOper(char val){
        return val == '+' || val == '-' || val == '*' || val == '/';
    }

    /**
     * 计算逆波兰表达式
     * @param list 用来存储表达式
     * @return 返回最终计算结果
     */
    public static double lastPolandExpression(List<String> list) {
        //创建一个栈
        Stack<String> stack = new Stack<>();
        //遍历存储表达式的list集合
        for (int i = 0; i < list.size(); i++) {
            char s = list.get(i).charAt(0);
            if (!isOper((s))) {
                //如果是数字
                String str = list.get(i);
                //入栈
                stack.push(str);
            }else {
                //如果是运算符,取出栈顶元素和次顶元素进行计算
                double num1 = Double.parseDouble( stack.pop() );
                double num2 = Double.parseDouble( stack.pop() );
                double result = cal(num1,num2,s);
                //最后将计算结果压入栈中
                stack.push(String.valueOf(result));
            }
        }
        //返回栈中的最后一个元素,就是计算结果
        return Double.parseDouble( stack.pop() );
    }


    public static double cal(double num1,double num2,int oper){
        double res = 0; // 存放计算结果
        switch (oper){
            case '+':
                res = num1 + num2;
                break;
            case '-':
                res = num2 - num1;
                break;
            case '*':
                res = num1 * num2;
                break;
            case '/':
                if (num1 == 0)
                    throw new RuntimeException("0不能作为除数!");
                res = num2 / num1;
                break;
            default:
                break;
        }
        return res;
    }

    public static List<String> getListString(String suffixExpression) {
        // 将suffixExpression按照空格分割
        String[] split = suffixExpression.split(" ");
        List<String> list = new ArrayList<>();
        for (String ele : split) {
            list.add(ele);
        }
        return list;
    }
}

如何将中缀表达式转换为后缀表达式

如何计算中缀表达式

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

终有弱水替沧海i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值