逆波兰表达式求值

力扣题目链接(opens new window)

根据 逆波兰表示法,求表达式的值。

有效的运算符包括 + , - , * , / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

说明:

整数除法只保留整数部分。 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。

示例 1:

  • 输入: ["2", "1", "+", "3", " * "]
  • 输出: 9
  • 解释: 该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9

示例 2:

  • 输入: ["4", "13", "5", "/", "+"]
  • 输出: 6
  • 解释: 该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6

示例 3:

  • 输入: ["10", "6", "9", "3", "+", "-11", " * ", "/", " * ", "17", "+", "5", "+"]

  • 输出: 22

  • 解释:该算式转化为常见的中缀算术表达式为:

    ((10 * (6 / ((9 + 3) * -11))) + 17) + 5
    = ((10 * (6 / (12 * -11))) + 17) + 5
    = ((10 * (6 / -132)) + 17) + 5
    = ((10 * 0) + 17) + 5
    = (0 + 17) + 5
    = 17 + 5
    = 22

逆波兰表达式:是一种后缀表达式,所谓后缀就是指运算符写在后面。

平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。

该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。

逆波兰表达式主要有以下两个优点:

  • 去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
  • 适合用栈操作运算:遇到数字则入栈;遇到运算符则取出栈顶两个数字进行计算,并将结果压入栈中。

思路

什么是逆波兰表达式

题目注释里面也提到了,逆波兰表达式是一种后缀表达式

那么什么的又是后缀表达式呢?这就要从平时我们习惯使用的表达式说起

例如:(1+2)*(3+4)

这种我们平时使用的表达式叫做:中序表达式,在顺序上是比较符合人类阅读的

但计算机读起来就得转换,而计算机可以直接读的就是后缀表达式

上面的中序表达式用二叉树来写就可以写成:

     *
/ \
+ +
/ \ / \
1 2 3 4

然后按照二叉树后续遍历(左右中,之后会学到)的顺序遍历上述二叉树得到:12+34+*

这个就是由来

用栈解决问题

与有效括号和删除字符串相邻字符类似,我们也是用栈进行一种类似"消消乐"的操作

代码

步骤

1、遍历字符串

  • 如果遇见运算符,从栈里取2个元素(取一个pop一个,一共取两次)
  • 判断遇到的运算符,做相应计算后push回栈中
  • 如果遇见数字,就把数字转成int类型然后存回栈里

2、遍历结束,返回栈中仅剩的一个元素

class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<long long> st;
//遍历字符串
for(int i = 0; i < tokens.size(); ++i){
if(tokens[i] == "+"|| tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/"){//遇到运算符
//取两个数
long long num1 = st.top();
st.pop();
long long num2 = st.top();
st.pop();
//判断运算符,做相应计算并压栈//注意计算顺序,num2[运算符]num1
if(tokens[i] == "+") st.push(num2 + num1);
if(tokens[i] == "-") st.push(num2 - num1);
if(tokens[i] == "*") st.push(num2 * num1);
if(tokens[i] == "/") st.push(num2 / num1);
}else{//遇到数字
//转为整型,压栈
st.push(stoll(tokens[i]));
}
}
int res = st.top();
st.pop();//内存回收
return res;
}
};

1、初始化栈的时候应该选择long long类型,其中的数也要是long long类型

2、取出num1、num2之后,计算时的顺序要正确,应该是num2[运算符]num1

3、补充知识:c++中用于将字符串类型转换为长整型的函数是

stol()(long int)和stoll()(long long int)

【LeetCode栈与队列#04】逆波兰表达式求值(仍然是经典的栈操作)的更多相关文章

  1. LeetCode:逆波兰表达式求值【150】

    LeetCode:逆波兰表达式求值[150] 题目描述 根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除 ...

  2. leetcode算法学习----逆波兰表达式求值(后缀表达式)

    下面题目是LeetCode算法:逆波兰表达式求值(java实现) 逆波兰表达式即后缀表达式. 题目:  有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式.同 ...

  3. 【python】Leetcode每日一题-逆波兰表达式求值

    [python]Leetcode每日一题-逆波兰表达式求值 [题目描述] 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说 ...

  4. 代码随想录算法训练营day11 | leetcode 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值

    基础知识 String StringBuilder 操作 public class StringOperation { int startIndex; int endIndex; { //初始容量为1 ...

  5. LeetCode 150. 逆波兰表达式求值(Evaluate Reverse Polish Notation) 24

    150. 逆波兰表达式求值 150. Evaluate Reverse Polish Notation 题目描述 根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, /.每个运算对象 ...

  6. Leetcode 150.逆波兰表达式求值

    逆波兰表达式求值 根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除法只保留整数部分. 给定逆波兰表达式总 ...

  7. Java实现 LeetCode 150 逆波兰表达式求值

    150. 逆波兰表达式求值 根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除法只保留整数部分. 给定逆波 ...

  8. SDIBT2666——逆波兰表达式求值

    逆波兰表达式求值(栈和队列) Description 从键盘上输入一个逆波兰表达式,用伪码写出其求值程序.规定:逆波兰表达式的长度不超过一行,以@符作为输入结束,操作数之间用空格分隔,操作符只可能有+ ...

  9. LeetCode150 逆波兰表达式求值

    根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除法只保留整数部分. 给定逆波兰表达式总是有效的.换句话说 ...

  10. 代码随想录第十三天 | 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素

    第一题150. 逆波兰表达式求值 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 注意 两个整数之间的除法只保留整数部分. ...

随机推荐

  1. 在web中,用户输入的文字过多 和页面排版一行显示不下 怎么办

    在写管理系统中, 如果用户在input中,表单输入过多,应该如何去处理 常用的解决办法是: 1==>用户只能够输入一定范围内的字数 2==>超出几个字后(宽度)使用省略号显示. 3==&g ...

  2. 洛谷P3101 题解

    输入格式 第 \(1\) 行,三个整数 \(m,n,t\). 第 \(2\) 到 \(m+1\) 行,\(m\) 个整数,表示海拔高度. 第 \(2+m\) 到 \(2m+1\) 行,\(m\) 个整 ...

  3. Fabric网络升级(总)

    原文地址在这里. 在fabric网络中,升级nodes和通道至最新版本需要四步: 备份账本和MSPs. 以滚动的方式将orderer升级到最新版. 以滚动的方式将peers升级到最新版. 将order ...

  4. Gorm 入门介绍与基本使用

    Gorm 入门介绍与基本使用 目录 Gorm 入门介绍与基本使用 一.ORM简介 1.1 什么是ORM 1.2 使用ORM的好处 1.2.1 避免直接操作SQL语句 1.2.2 提高代码的可维护性 1 ...

  5. 【转载】基于Tablestore Timeline的IM(即时通讯)消息系统架构 - 架构篇

    本文原作者:木洛,阿里云高级技术专家,内容有优化和修订,感谢原作者.原文链接:https://developer.aliyun.com/article/698301 IM全称是『Instant Mes ...

  6. NSSCTF Round#17 Basic CRYPTO

    Level_1 题目 Level_1.py(我把参数整理了一下,看着舒服) #真签到题 from Crypto.Util.number import bytes_to_long, getPrime f ...

  7. 在Unity中使用SQLite保存配置表数据(For Lua)

    在Lua中使用sqlite Lua版本Sqlite文档:http://lua.sqlite.org/index.cgi/doc/tip/doc/lsqlite3.wiki sqlite官网:https ...

  8. C/C++ 简易异或加密的分析

    异或,加解密shellcode代码的简单分析方法. #include <stdio.h> #include <Windows.h> unsigned char buf[] = ...

  9. C# 中的函数与方法

    在C#中,函数和方法都是一段可重用的代码块,用于实现特定的功能.函数是C#中的基本代码块之一,用于完成特定的任务和返回一个值.函数可以具有零个或多个参数,并且可以使用关键字来指定函数的访问级别和返回类 ...

  10. PLSQL Developer汉语设置

    PLSQLQ Developer是由Oracle公司推出的数据库开发工具,具有很好的移植性和适应性.但是当我们安装完成Oracle11g PLSQL Developer工具后发现状态栏的显示是英文,对 ...