LeetCode: Evaluate Reverse Polish Notation

本文详细介绍了如何将四则运算表达式解析为逆波兰式(后缀表达式),并通过递归算法计算其值。重点在于利用后续遍历的特性,以及在递归过程中如何确定和处理树结构中的每个节点,特别是如何在无法预先知道左子树根节点位置的情况下,通过不断摘除节点来解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

于是考虑使用递归,即:

1.找到根节点;

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

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

  计算右子树值;

   计算左子树值;

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

但是在上面的3中,左子树的根节点位置是无法再访问其根节点时确定的,解决办法就是在递归过程中,不断"摘掉"每个访问过的点,这样一来当右子树计算结束时,右子树的所有节点都被“摘下”,于是此时tokens中最顶端的结点一定就是左子树的根节点。这大概也就是为什么题目中的方法默认采用非const引用参数的原因吧。

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());
    }
};

 

 

转载于:https://www.cnblogs.com/zanghu/p/3619001.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值