栈的应用-四则运算表达式求值

后缀表达式(逆波兰表达式)计算结果


实现思路

后缀表达式的特点:运算符总是放在跟它相关的操作数之后
在这里插入图片描述

为了解释后缀表达式的好处,我们先来看看,计算机如何应用后缀表达式计算出最终的结果

后缀表达式:9 3 1 - 3 * + 10 2 / +

规则:从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号就将处于栈顶两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果。

  1. 初始化一个空栈,此栈用来对要运算的数字进出使用
    在这里插入图片描述

  2. 后缀表达式中前三个都是数字,所以9、3、1进栈
    在这里插入图片描述

  3. 接下来是 - ,所以将栈中的1出栈作为减数,3出栈作为被减数,算出3-1=2,再将2进栈
    在这里插入图片描述

  4. 接着是数字3进栈
    在这里插入图片描述

  5. 后面是 *,也就意味着栈中3和2出栈,2与3相乘,得到6,并将6进栈
    在这里插入图片描述

  6. 下面是 +,所以栈中6和9出栈,算出8+6=15,将15进栈
    在这里插入图片描述

  7. 接着是10和2进栈
    在这里插入图片描述

  8. 接下来是 /,因此栈顶2和10出栈,10与2相除,得到5,将5进栈
    在这里插入图片描述

  9. 最后一个符号是 +,所以15和5出栈相加,得到20,将20进栈

  10. 结果是20出栈,栈变为空

代码实现

public class Test {
    public static void main(String[] args) {
        String[] str = {"9", "3", "1", "-", "3", "*", "+", "10", "2", "/", "+"};
        System.out.println(Test.evalRPN(str));
        //输出为20
    }

    public static int evalRPN(String[] strings){
        Stack<Integer> stack = new Stack<>();
        for (String s : strings) {
            if ("+" == s){
                stack.push(stack.pop() + stack.pop());
            }else  if ("-" == s){
                stack.push(-stack.pop() + stack.pop());
            }else if ("*" == s){
                stack.push(stack.pop() * stack.pop());
            }else if ("/" == s){
                Integer temp1 = stack.pop();
                Integer temp2 = stack.pop();
                stack.push(temp2 / temp1);
            }else {
                stack.push(Integer.valueOf(s));
            }
        }
        return stack.pop();
    }
}

中缀表达式转后缀表达式

我们把平时所用的标准四则运算表达式叫做中缀表达式。

中缀表达式:9+(3-1)*3+10/2

规则:从左到右遍历中缀表达式中的每个数字和符号,若是数字就输出;若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低于栈顶符号则栈顶元素依次出栈并输出,并将当前符号进栈,一直到最终输出后缀表达式为止。

实现思路

  1. 初始化一个空栈,此栈用来对符号进出使用
    在这里插入图片描述

  2. 第一个是数字9,输出09,后面是符号 +,进栈
    在这里插入图片描述

  3. 第三个是 (,依然是符号,因其只是左括号,还未配对,故进栈
    在这里插入图片描述

  4. 第四个是数字3,输出,总表达式为9 3,接着是 -,进栈
    在这里插入图片描述

  5. 接下来是数字1,输出,总表达式为9 3 1,后面是 ),此时,我们需要去匹配此前的 (,所以依次出栈并输出,直到 (出栈为止。总的表达式为9 3 1 -
    在这里插入图片描述

  6. 接着是数字3,输出,总的表达式为9 3 1 - 3。紧接着是符号 * ,因为此时的栈顶元素为 +,优先级低于 * ,因此不输出, *进栈
    在这里插入图片描述

  7. 之后是符号 +,此时当前栈顶元素为 *,因此栈中元素出栈并输出(没有比 + 号更低的优先级,所以全部出栈)。总输出表达式为9 3 1 - 3 * +。然后将当前这个符号 +进栈。
    在这里插入图片描述

  8. 紧接着是数字10,输出,总表达式为9 3 1 - 3 * + 10,后面是符号 /,所以 / 进栈
    在这里插入图片描述

  9. 最后一个数字2,输出,总表达式为9 3 1 - 3 * + 10 2

  10. 因为已经到了最后,所以将栈中符号全部出栈

最后得到的后缀表达式为9 3 1 - 3 * + 10 2 / +

代码实现

public class Test {
    public static void main(String[] args) {
        String[] str = {"9", "+", "(", "3", "-", "1", ")", "*", "3", "+", "10", "/", "2"};
        System.out.println(Test.toRPN(str));
    }

    public static String toRPN(String[] strings) {
        StringBuilder sb = new StringBuilder();
        Stack<String> stack = new Stack<>();
        for (String s : strings) {
            if ("+" == s || "-" == s) {
                if (!stack.isEmpty() && (stack.peek() == "*" || stack.peek() == "/")) {
                    while (!stack.isEmpty()) {
                        sb.append(stack.pop());
                    }
                }
                stack.push(s);
            } else if ("(" == s) {
                stack.push(s);
            } else if (")" == s) {
                while (stack.peek() != "(") {
                    sb.append(stack.pop());
                }
                stack.pop();
            } else if ("*" == s || "/" == s) {
                stack.push(s);
            }else {
                sb.append(Integer.valueOf(s));
            }
        }
        while (!stack.isEmpty()) {
            sb.append(stack.pop());
        }
        return sb.toString();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值