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

更详细的讲解和代码调试演示过程,请参看视频

如何进入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,也就是说,我们代码对算法的实现应该是正确的。

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

时间: 2024-10-07 21:47:45

面试算法:利用堆栈计算逆向波兰表达式的相关文章

【LeetCode刷题Java版】Evaluate Reverse Polish Notation(计算逆波兰表达式)

Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, *, /. Each operand may be an integer or another expression. Some examples: ["2", "1", "+", "3", "*"] -&g

[Leetcode] evaluate reverse polish notation 计算逆波兰表达式

Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are+,-,*,/. Each operand may be an integer or another expression. Some examples: ["2", "1", "+", "3", "*"] -> (

北京大学 程序设计与算法(二)逆波兰表达式

用递归解决递归形式的问题 逆波兰表达式 逆波兰表达式是一种把运算符前置的算数表达式,例如普通的表达式2+3的逆波兰表示法为+2 3.逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2+3)*3的逆波兰表示法为*+234.本题求解逆波兰表达式的值,其中运算符包括+-*/四个. 输入 输入为一行,其中运算符和运算数之间都用空格分隔,运算符是浮点数 输出 输出为一行,表达式的值. *+11.0 12.0 +24.0 35.0 --à(11.0+12.0)*(24.0+3

栈的应用---用栈计算逆波兰表达式

#include<stdio.h> #include<stdlib.h> struct Node; typedef struct Node *PtrToNode; typedef PtrToNode Stack; struct Node{ int Ele; PtrToNode Next; }; Stack CreateStack( void ) { Stack S; S = malloc( sizeof( struct Node ) ); if(S == NULL ) printf

JavaScript实现计算后缀表达式(逆波兰表达式)以及将中缀表达式转为后缀表达式

逆波兰表达式,它的语法规定,表达式必须以逆波兰表达式的方式给出.逆波兰表达式又叫做后缀表达式.这个知识点在数据结构和编译原理这两门课程中都有介绍,下面是一些例子: 正常的表达式 逆波兰表达式 a+b ---> a,b,+ a+(b-c) ---> a,b,c,-,+ a+(b-c)d ---> a,d,b,c,-,,+ a=1+3 ---> a=1,3 + http=(smtp+http+telnet)/1024 写成什么呢? http=smtp,http,telnet,+,+,1

栈,逆波兰表达式???

这两天一直在想老师提出的要求:四个数的运算,让一个函数去实现,一次性的把四个数字以及三个运算符传递过去(数是随机产生的,运算符是随机产生的),说到随机产生运算符下面是我写的随机产生运算符的例子,但是还是没有达到自己想要的要求,自己也上网查了一些资料,但是介绍的都不是很详细,看不太懂,而且大部分都是些怎么不让其产生重复的元素. 这样写的结果是有些情况永远也出不来而且这样写的结果就好像是每一个数组里面的元素就好像是商量好了一样,说第几个元素出来就第几个元素出来,请求老师指导一下. 还说四个数的运算吧

【算法】逆波兰表达式

表达式一般由操作数(Operand).运算符(Operator)组成,例如算术表达式中,通常把运算符放在两个操作数的中间, 这称为中缀表达式(Infix Expression),如A+B. 波兰数学家Jan Lukasiewicz提出了另一种数学表示法,它有两种表示形式: 把运算符写在操作数之前,称为波兰表达式(Polish Expression)或前缀表达式(Prefix Expression),如+AB: 把运算符写在操作数之后,称为逆波兰表达式(Reverse Polish Express

调度场算法与逆波兰表达式

本文的主要内容是如何求一个给定的表达式的值,具体思路就是先将普通算术的中缀表达式转化为后缀表达式,这一步用到的算法叫做调度场算法.然后对后缀表达式,也就是逆波兰表达式求值. 题目:http://acm.hdu.edu.cn/showproblem.php?pid=3596 代码:(参考别人的重构) #include <iostream> #include <string.h> #include <stdio.h> #include <math.h> #inc

【LeetCode-面试算法经典-Java实现】【151-Evaluate Reverse Polish Notation(计算逆波兰式)】

[151-Evaluate Reverse Polish Notation(计算逆波兰式)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, *, /. Each operand may be an integer or another expression. Some