面试算法:利用堆栈计算逆向波兰表达式

Posted tyler_download

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试算法:利用堆栈计算逆向波兰表达式相关的知识,希望对你有一定的参考价值。

更详细的讲解和代码调试演示过程,请参看视频
如何进入google,算法面试技能全面提升指南

给定一个四则运算表达式的字符串,如果该表达式满足逆向波兰表达式,那么该字符串要满足以下条件:

1: 该表达式含有一个数字字符或一串数字字符。

2:它拥有给定格式,如”A, B, 。“,其中A,B是逆向波兰表达式,句号。表示的是四种运算符”+,-,*,/”其中之一。

例如字符串“3,4,*,1,2,+,+”就满足逆向波兰表达式,该表达式的值为:3 * 4 + (1+2) = 15.

给定一个逆向波兰表达式,要求计算该表达式的值。

处理算法题时,选择合适的数据结构,相当于把问题解决掉了一大半。处理逆向波兰表达式最好的数据结构是堆栈,算法如下:

1, 如果当前字符是数字,那么把数字压入堆栈。

2, 如果当前字符是运算符,那么从堆栈中弹出两个元素,做相应计算,然后把结果压入堆栈

3, 当所有字符处理完毕后,堆栈上包含的数值就是表达式的值。

我们根据给定例子,把上面的算法走一遍。
第一个字符是数字字符3,所以压入堆栈:
char: 3
stack: 3

第二个字符是数字4,所以压入堆栈
char: 3, 4
stack: 3, 4

第三个字符是运算符,因此把堆栈上头的两个元素弹出,做相应计算,然后把结果压入堆栈:

char: 3, 4, *
stack:12

第四个字符是数字,因此压入堆栈:
char: 3, 4, *, 1
stack: 12, 1

第五个字符是数字2,因此压入堆栈:
char: 3, 4, * , 1, 2
stack: 12, 1, 2

第六个字符是运算符,因此弹出堆栈顶部的两个元素做相应计算
char: 3, 4, *, 1, 2, +
stack: 12, 3

第七个字符是运算符,因此弹出堆栈顶部两个元素做计算:
char: 3, 4, *, 1, 2, +, +
stack: 15

到此字符处理完毕,堆栈上的数值15就是表达式的结果。我们再看看相应的代码实现:

import java.util.Stack;


public class ReversePolishExpr {
    private String expression;
    Stack<Integer> stack = new Stack<Integer>();

    public ReversePolishExpr(String expr) {
        this.expression = expr;
    }

    public int calculation() throws Exception {
        String[] exprs = expression.split(",");

        for (int i = 0; i < exprs.length; i++) {
            if (isOperator(exprs[i]) && stack.size() < 2) {
                throw new Exception("Expression error");
            }

            if (isOperator(exprs[i])) {
                doCalculation(exprs[i]);
            }
            else {
                stack.push(Integer.valueOf(exprs[i]));  
            }

        }

        return stack.pop();
    }


    private boolean isOperator(String c) {
        if (c.equals("+") == true || c.equals("-") == true  ||
                c.equals("*") == true || c.equals("/") == true) {
            return true;
        }

        return false;
    }

    private void doCalculation(String c) {
        int op1 = stack.pop();
        int op2 = stack.pop();

        switch (c) {
        case "+":
            stack.push(op1 + op2);
            break;
        case "-":
            stack.push(op1 - op2);
            break;
        case "*":
            stack.push(op1*op2);
            break;
        case "/":
            stack.push(op1/op2);
            break;
        }
    }
}

上面代码实现的正是前头说明的算法步骤,我们先把含有逗号分隔的字符串分成相应部分,在for循环中判断,如果遇到的是数字,那么把它压入堆栈,如果遇到的是运算符,那么把数字从堆栈上弹出,做相应计算,把计算结果再压入堆栈。最后我们再看看主入口函数:

public class StackAndQuque {
    public static void main(String[] args) {
        ReversePolishExpr rp = new ReversePolishExpr("3,4,*,1,2,+,+");
        try {
            System.out.println("The result of reverse polish express is " + rp.calculation());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

运行上面代码后得到的输出结果是:
The result of reverse polish express is 15

也就是说,给定的逆向波兰表达式的结果确实是15,也就是说,我们代码对算法的实现应该是正确的。

更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号:
这里写图片描述

以上是关于面试算法:利用堆栈计算逆向波兰表达式的主要内容,如果未能解决你的问题,请参考以下文章

重新整理数据结构与算法——逆波兰表达计算器[八]

C语言编程-逆波兰表达式求值

数据结构&算法-逆波兰四则运算

数据结构&算法-逆波兰四则运算

算法与数据结构--栈的应用-逆波兰计算器完整版代码

Qz学算法-数据结构篇(表达式递归)