首页 > 其他 > 详细

LeetCode: Evaluate Reverse Polish Notation

时间:2014-03-23 17:25:38      阅读:358      评论:0      收藏:0      [点我收藏+]

波兰式:将四则运算的表达式解析成一棵二叉树,后续遍历之,得到的字符串序列就是逆波兰式,也叫后缀表达式。

一开始考虑时,首先想到建立两个栈,一个栈是数字栈,一个栈是操作符栈,但是实现了一下发现不可行,重新分析发现理论上也是错误的。

考虑到后缀表达式的性质,可以很容易的确定根节点和右子树根节点(如果有的话)。四则运算表达式的二叉树的每个非叶子结点一定有两个孩子。

于是考虑使用递归,即:

1.找到根节点;

2.如果根节点数字,则返回其值;

3.如果根节点是算符op,则

  计算右子树值;

   计算左子树值;

   返回:左子树值op右子树值

但是在上述3中,左子树的根节点位置是难以确定的,解决办法就是在递归过程中,不断"摘掉"每个访问过的点。这大概也就是为什么题目中的方法默认采用非const引用参数的原因吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Solution {
    //实现字符串op的四则运算算符效果
    int operation(int n1, int n2, const string& op) { 
        switch ((op.c_str())[0]) {
            case ‘+‘: return n1 + n2;
            case ‘-‘: return n1 - n2;
            case ‘*‘: return n1 * n2;
            case ‘/‘: return n1 / n2;
        }
    }
public:
    //非常精巧的递归,基本思想是利用后续遍历计算树的性质
    int evalRPN(vector<string>& tokens) {
        //每一次递归视作是从根节点开始计算一个树形算式,由于tokens中是后序序列,因此根节点位于最末端
        string str = tokens.back(); //读取根节点值
        //摘下根节点,这是由于递归时,只能预测有字数根节点的位置,无法预测左子树根节点位置,
        //因此必须不断摘掉树的节点,直到该字数计算完毕为止
        vec.pop_back();
        //如果根节点是算符,则先计算左子树值,再计算右子树值,最后用根节点算符对两个数运算,返回
        //如果根节点是数字,则说明到达叶子节点,直接看做常量表达式,返回
        if (str == "+" || str=="-" || str=="*" || str=="/") { 
            int r_num = evalRPN(tokens);
            int l_num = evalRPN(tokens);
            return operation(l_num, r_num, str);
        }
        else return atoi(str.c_str());
    }
};

LeetCode: Evaluate Reverse Polish Notation,布布扣,bubuko.com

LeetCode: Evaluate Reverse Polish Notation

原文:http://www.cnblogs.com/zanghu/p/3619001.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!