【stack题解】逆波兰表达式求值 | 用队列实现栈

逆波兰表达式求值

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。

请你计算该表达式。返回一个表示表达式值的整数。

注意:

有效的算符为 '+'、'-'、'*' 和 '/' 。 每个操作数(运算对象)都可以是一个整数或者另一个表达式。 两个整数之间的除法总是 向零截断 。 表达式中不含除零运算。 输入是一个根据逆波兰表示法表示的算术表达式。 答案及所有中间计算结果可以用 32 位 整数表示。

示例 1:

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

示例 2:

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

示例 3:

输入:tokens = ["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+10/5,这是一种中缀表达式,即运算符在中间,操作数在两边。

而中缀表达式并不适合计算机去计算,计算机是从左往右读取值的:1 + 10 / 5,这样计算的结果就是11/5=2。

为了贴合计算机的读取方式,我们就可以用后缀表达式,即操作数在前,相对顺序不变;运算符按照优先级的顺序,排列在后。

1+10/5改成后缀表达式为:1 10 5 / +

当从左往右读到 / 时,要把前两个操作数取出来运算,这种结构,让我们想到了

实现

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<int> st;
        for(auto str:tokens){
            if(str=="+"||str=="-"||str=="*"||str=="/"){
                int right=st.top();
                st.pop();
                int left=st.top();
                st.pop();
​
                switch(str[0]){
                    case '+':
                    st.push(left+right);
                    break;
                    case '-':
                    st.push(left-right);
                    break;
                    case '*':
                    st.push(left*right);
                    break;
                    case '/':
                    st.push(left/right);
                    break;
                }
            }
            else{
                st.push(stoi(str));
            }
        }
        return st.top();
    }
};

用队列实现栈

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。

实现 MyStack 类:

void push(int x) 将元素 x 压入栈顶。 int pop() 移除并返回栈顶元素。 int top() 返回栈顶元素。 boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

注意:

你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。

示例:

输入:["MyStack", "push", "push", "top", "pop", "empty"]    
[[], [1], [2], [], [], []]
​
输出:[null, null, null, 2, 2, false]

解释:

MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False

提示:

1 <= x <= 9 最多调用100 次 push、pop、top 和 empty 每次调用 pop 和 top 都保证栈不为空

进阶:你能否仅用一个队列来实现栈。

初级:用两个栈实现

两个栈q1、q2。当q1不为空,q2为空时,入数据就直接往q1入。删数据时,先把q1中不删的数据都入到q2中,再删q1的数。

class MyStack {
public:
    queue<int> q1,q2;
​
    MyStack() {
    }
    
    void push(int x) {
        if(!q1.empty()){
            q1.push(x);
        }
        else{
            q2.push(x);
        }
    }
    
    int pop() {     
        if(q1.empty()){
            int num=q2.size()-1;
            while(num--){
                q1.push(q2.front());
                q2.pop();
            }
            int ret=q2.front();
            q2.pop();
            return ret;
        }
        else{
            int num=q1.size()-1;
            while(num--){
                q2.push(q1.front());
                q1.pop();
            }
            int ret=q1.front();
            q1.pop();
            return ret;
        }
    }
    
    int top() {
        if(!q1.empty()){
            return q1.back();
        }
        else{
            return q2.back();
        }
    }
    
    bool empty() {
        return q1.empty()&&q2.empty();
    }
};

进阶:用一个栈实现

这个方法非常巧妙。我们就用一个队列,插入就直接入队列;删除的话,把 末尾元素之前的全部元素 出队,再重新入队,这样,队列的首元素就是栈顶元素了。此时再pop。

class MyStack {
public:
    queue<int> q;
    MyStack() {
​
    }
    
    void push(int x) {
        q.push(x);
    }
    
    int pop() {
        int num=q.size()-1;  //把末尾元素之前的元素 都重新入队列
        while(num--){
            q.push(q.front());
            q.pop();
        }
        int ret=q.front();  //先记录栈顶元素,再删
        q.pop();
        return ret;
    }
    
    int top() {
        return q.back();
    }
    
    bool empty() {
        return q.empty();
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/142675.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《深入浅出进阶篇》——空间换时间优化——P2671 求和

链接&#xff1a;https://www.luogu.com.cn/problem/P2671 上题干&#xff1a; 题目描述 一条狭长的纸带被均匀划分出了n个格子&#xff0c;格子编号从11到n。每个格子上都染了一种颜色colori​用[1,m]当中的一个整数表示&#xff09;&#xff0c;并且写了一个数字numberi​。…

arm2 day6

串口实现单个字符的收发 main.c uart4.c uart4.h

手机厂商参与“百模大战”,vivo发布蓝心大模型

在2023 vivo开发者大会上&#xff0c;vivo发布自研通用大模型矩阵——蓝心大模型&#xff0c;其中包含十亿、百亿、千亿三个参数量级的5款自研大模型&#xff0c;其中&#xff0c;10亿量级模型是主要面向端侧场景打造的专业文本大模型&#xff0c;具备本地化的文本总结、摘要等…

HTML设置标签栏的图标

添加此图标最简单的方法无需修改内容&#xff0c;只需按以下步骤操作即可&#xff1a; 1.准备一个 ico 格式的图标 2.将该图标命名为 favicon.ico 3.将图标文件置于index.html同级目录即可 为什么我的没有变化&#xff1f; 答曰&#xff1a;ShiftF5强制刷新一下网页就行了

湖南省第六届大学生测绘综合技能大赛 GIS 应用赛项

注意事项&#xff1a; ①确认试题编号正确后再开始作答。 ②所有图件需清晰可辨。 ③新建数值型字段设置数据类型为双精度&#xff0c;数字格式为数值&#xff0c;小数位数默认。 ④答卷中不能出现任何涉密信息&#xff0c;答卷文档转成PDF提交。 1.&#xff08;25 分&#xf…

Oracle数据库、实例、用户、表空间和表之间的关系

一、Oracle数据库中数据库、实例、用户、表空间和表&#xff08;索引、视图、存储过程、函数、对象等对象&#xff09;之间的关系。 1、Oracle的数据库是由一些物理文件组成&#xff1a;数据文件控制文件重做日志文件归档日志文件参数文件报警和跟踪日志文件备份文件。 2、实…

数据库 并发控制

多用户数据库系统&#xff1a;允许多个用户同时使用同一个数据库的数据库系统 交叉并发方式&#xff1a;在单处理机系统中&#xff0c;事务的并行执行实际上是这些并行事务的并行操作轮流交叉运行 同时并发方式&#xff1a;在多处理机系统中&#xff0c;每个处理机可以运行一个…

云原生实战课大纲

1. 云原生是什么 原生应用&#xff08;java,pyrhon&#xff09; 上云的过程应用上云遇到的问题1.微服务的拆分 微服务的访问关系应用的架构云原生适合什么样的人去学具备什么样的前提条件云原生要学习什么docker k8s devlops server mesh jks k8s监控吧自己的微服务上云另…

【C语言】

C语言 1. C语言基础1.1 数据类型和占位符1.2 异或1.3 关键字1.4 const1.5 extern1.6 typedef1.7 static1.8 左值和右值1.9 位进行操作赋值 2. C指针3. 二维数组和指针4. 函数传递二维数组4.1 形参给出第二维的长度。4.2 形参声明为指向数组的指针。4.3 形参声明为指针的指针。 …

如何使用免费的 Vecteezy 旅行视频

网址&#xff1a;https://www.vecteezy.com/ Vecteezy 是一个提供免费和付费矢量图形、模板、视频和其他创意资源的网站。该网站拥有大量旅行视频&#xff0c;可用于各种目的&#xff0c;例如个人使用、商业用途或教育用途。 要下载 Vecteezy 的免费旅行视频&#xff0c;请按…

阿里云服务器u1和经济型e实例有什么区别?

阿里云服务器ECS经济型e实例和通用算力型u1实例有什么区别&#xff1f;如何选择&#xff1f;ECS经济型e实例是共享型云服务器&#xff0c;通用算力型u实例是企业级独享型云服务器&#xff0c;e实例性价比高&#xff0c;现在2核2G3M带宽一年99元&#xff0c;云服务器u1价格相对要…

什么是权限?(Linux篇)

前言 其实我们在学会运用一些简单的Linux指令之后&#xff0c;我们可以简单的用ls查看当前目录的文件有哪些啊&#xff0c;可以使用tree用树形结构查看目录&#xff0c;可以使用touch来创建文件&#xff0c;用mkdir创建目录&#xff0c;可以使用rm来删除目录和文件&#xff0c;…

C#,数值计算——多项式计算,Poly的计算方法与源程序

1 文本格式 using System; using System.Text; namespace Legalsoft.Truffer { /// <summary> /// operations on polynomials /// </summary> public class Poly { /// <summary> /// polynomial c[0]c[1]xc[2]x^2 ..…

高频SQL50题(基础题)-5

文章目录 主要内容一.SQL练习题1.602-好友申请&#xff1a;谁有最多的好友代码如下&#xff08;示例&#xff09;: 2.585-2016年的投资代码如下&#xff08;示例&#xff09;: 3.185-部门工资前三高的所有员工代码如下&#xff08;示例&#xff09;: 4.1667-修复表中的名字代码…

数据库恢复技术

事务 含义&#xff1a;用户定义的一个数据库操作序列&#xff0c;这些操作要么全做&#xff0c;要么全不做&#xff0c;是一个不可分割的工作单位 地位&#xff1a;恢复和控制并发的基本单位 区分事务和程序&#xff0c;一个程序中包含多个事务 定义事务 事务的开始与结束…

[linux网络实验] 多网卡绑定

聚合链路技术 什么是bonding 提供了一种将多个网络接口设备绑定到一个网络接口的方法。这可用于网络负载平衡和网络冗余&#xff1b; 实现将两个网卡虚拟成一个网卡。这种聚合设备看起来就像一个以太网接口设备。通俗地说&#xff0c;这意味着两个网卡拥有相同的 IP 地址&am…

PostgreSQL 机器学习插件 MADlib 安装与使用

MADlib 一个可以在数据库上运行的开源机器学习库&#xff0c;支持 PostgreSQL 和 Greenplum 等数据库&#xff1b;并提供了丰富的分析模型&#xff0c;包括回归分析&#xff0c;决策树&#xff0c;随机森林&#xff0c;贝叶斯分类&#xff0c;向量机&#xff0c;风险模型&#…

Leetcode刷题详解——黄金矿工

1. 题目链接&#xff1a;1219. 黄金矿工 2. 题目描述&#xff1a; 你要开发一座金矿&#xff0c;地质勘测学家已经探明了这座金矿中的资源分布&#xff0c;并用大小为 m * n 的网格 grid 进行了标注。每个单元格中的整数就表示这一单元格中的黄金数量&#xff1b;如果该单元格…

数据库表的设计——范式

目录 1. 设计数据表需要注意的点 2. 范式 2.1 范式简介 2.2 范式有哪些&#xff1f; 2.3 第一范式(1NF) 2.4 第二范式(2NF) 2.5 第三范式(3NF) 2.6 小结 1. 设计数据表需要注意的点 &#xff08;1&#xff09;首先要考虑设计这张表的用途&#xff0c;这张表都要存放什…

博捷芯BJCORE:国内划片机品牌优势

国内划片机品牌在半导体设备制造领域奋起直追&#xff0c;展现出以下几个优势&#xff1a; 1. 技术提升&#xff1a;国内划片机品牌在技术上持续取得突破&#xff0c;例如设备精准度和切割精度的提高&#xff0c;可以在短时间内完成大量加工&#xff0c;提高了生产效率。 2. 适…