【算法入门-栈】逆波兰表达式求值

📖逆波兰表达式求值

      • ✅描述
      • ✅扩展:什么是逆波兰表达式
      • ✅题解方法一:栈
      • ✅题解方法二(数组模拟栈)

今天又刷了一道题,奥利给
刷题地址: 点击跳转

✅描述

给定一个逆波兰表达式,求表达式的值。

数据范围:表达式长度满足 1≤𝑛≤104 1≤n≤104 ,表达式中仅包含数字和 + ,- , * , / ,其中数字的大小满足 ∣𝑣𝑎𝑙∣≤200 ∣val∣≤200 。

示例1

输入:

["2","1","+","4","*"]

返回值:

12

示例2

输入:

["2","0","+"]

返回值:

2

✅扩展:什么是逆波兰表达式

表达式一般由操作数(Operand)、运算符(Operator)组成,例如算术表达式中,通常把运算符放在两个操作数的中间,这称为中缀表达式(Infix Expression),如A+B。

波兰数学家Jan Lukasiewicz提出了另一种数学表示法,它有两种表示形式:

把运算符写在操作数之前,称为波兰表达式(Polish Expression)或前缀表达式(Prefix Expression),如+AB;把运算符写在操作数之后,称为逆波兰表达式(Reverse Polish Expression)或后缀表达式(Suffix Expression),如AB+;前后缀表达式的出现是为了方便计算机处理,它的运算符是按照一定的顺序出现,所以求值过程中并不需要使用括号来指定运算顺序,也不需要考虑运算符号(比如加减乘除)的优先级。

先介绍中简单的人工转化方法:

假设有一个中缀表达式a+b*c-(d+e):

  1. 首先将这个中缀表达式的所有运算加括号((a+(b*c))-(d+e))
  2. 然后将所有运算符放到括号后面,这样就变成了((a(bc)* )+ (de)+ )-
  3. 把所有括号去掉abc*+de±,最后得出的结果就是后缀表达式。

✅题解方法一:栈

具体做法:

逆波兰表达式可以看成一种后序表达式,只需要在遇到符号的时候计算它前面两个数字即可,因此可以使用栈的先进后出原理。

遍历整个字符串数组,遇到数字就将其从字符串转变成int数字,然后加入栈中等待计算。遇到符号先取出栈中最后一位,然后与取出后的最后一位计算,结果存入最后一位,如下图所示:

alt

public int evalRPN (String[] tokens) {
        Stack<Integer> stack = new Stack<>();
        for (int i = 0; i < tokens.length; i++) {
            if (tokens[i].equals("+") || tokens[i].equals("-") || tokens[i].equals("*") || tokens[i].equals("/")) {
                if (tokens[i].equals("+")) {
                    stack.push(stack.pop() + stack.pop());
                }else if (tokens[i].equals("-")) {
                    stack.push(-stack.pop() + stack.pop());
                }else if (tokens[i].equals("*")) {
                    stack.push(stack.pop() * stack.pop());
                }else if (tokens[i].equals("/")) {
                    int a = stack.pop();
                    int b = stack.pop();
                    stack.push(b / a);
                }
            }else {
                stack.push(Integer.parseInt(tokens[i]));
            }
        }
        return stack.pop();
    }

复杂度分析:

  • 时间复杂度:𝑂(𝑛)O(n),遍历整个字符串数组
  • 空间复杂度:𝑂(𝑛)O(n),栈空间最大为数组长度,即全是数字

✅题解方法二(数组模拟栈)

与方法一的思路差不多,不过可以考虑使用数组来模拟栈。

假设逆波兰表达式中总共有n个元素,则n必定是奇数,并且数字的个数恰好比运算符个数多1。因为起初只有1个数字时,每加一个运算符,必定会加1个数字,依次类推,数字恰好比运算符多1。所以数字个数有(𝑛+1)/2(n+1)/2个,运算符个数有(𝑛−1)/2(n−1)/2个。用栈模拟的过程中,每次遇到数字,直接压入栈中,栈的容量会加1,遇到运算符时,先弹出两个元素,做运算后再压入栈中,栈的容量会减1。最坏情况下,数字全在前面,运算符全在后面,栈的容量最多达到(𝑛+1)/2(n+1)/2。

我们初始化arr数组的容量为(𝑛+1)/2(n+1)/2。用一个变量index指向栈顶的位置,index为-1表示栈容量为0。当压栈时,index加1,再将元素赋给当前位置,弹栈时,index减1即可。

public int evalRPN (String[] tokens) {
       int n = tokens.length;
       int[] arr = new int[(n+1)/2];
       int index = -1;
        for (String token : tokens) {
            if (!(token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/"))){
                arr[++index] = Integer.parseInt(token);
            }else {
                if (token.equals("+")){
                    index--;
                    arr[index] += arr[index+1];
                }else if (token.equals("-")){
                    index--;
                    arr[index] -= arr[index+1];
                }else if (token.equals("*")){
                    index--;
                    arr[index] *= arr[index+1];
                }else if (token.equals("/")){
                    index--;
                    arr[index] /= arr[index+1];
                }
            }
        }
        return arr[0];
    }

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

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

相关文章

vue3+vite项目添加项目环境变量配置文件(.env),import.meta.env

.env: VITE_KEY 123获取环境变量&#xff1a; let env import.meta.env console.log(env, env) 人工智能学习网站 https://chat.xutongbao.top

RAG应用的典型工作流程

下面是RAG应用的典型工作流程&#xff1a; 具体步骤如下&#xff1a; 输入&#xff1a; 是指LLM系统需要回答的问题。如果不使用RAG&#xff0c;问题直接由LLM回答。 索引&#xff1a; 使用RAG时&#xff0c;会先将相关文档分块&#xff0c;为这些块生成嵌入向量&#xff0c;并…

期权交易必须弄懂的期权波动率是什么?

今天带你了解期权交易必须弄懂的期权波动率是什么&#xff1f;波动率是金融资产价格波动的度量&#xff0c;它衡量了资产的收益率的不确定性&#xff0c;常用于反映金融资产的风险水平。 期权波动率是衡量资产价格偏离平均值的程度&#xff0c;偏离程度越大&#xff0c;期权波…

3D云渲染工具对决:Maya与Blender的性能和功能深度比较

3D建模和动画制作已成为数字领域不可或缺的一环&#xff0c;无论是在影视特效的震撼场面&#xff0c;还是在游戏角色的生动表现&#xff0c;3D技术都扮演着至关重要的角色。而在这一领域&#xff0c;Maya和Blender这两款软件&#xff0c;以其强大的功能和广泛的应用&#xff0c…

[ACM独立出版]2024年虚拟现实、图像和信号处理国际学术会议(ICVISP 2024)

[ACM独立出版]2024年虚拟现实、图像和信号处理国际学术会议&#xff08;ICVISP 2024&#xff09; 2024 International Conference on Virtual Reality, Image and Signal Processing 最新消息ICVISP 2024-已通过ACM出版申请投稿免费参会&#xff0c;口头汇报或海报展示(可获得…

产品使用手册深度剖析:五步快速敲定产品手册策划思路

引言 在这个信息爆炸的时代&#xff0c;产品使用手册不仅是产品的“说明书”&#xff0c;更是品牌与用户之间建立情感连接的桥梁。一份优秀的手册&#xff0c;能够迅速吸引用户的注意力&#xff0c;引导他们轻松上手&#xff0c;并深入体验产品的魅力。那么&#xff0c;如何撰…

usbserver工程师手记(二)设置定时任务

概述 部分银行ukey 长时间不使用后会导致休眠&#xff0c;出现虽然有连接&#xff0c;但是读不到证书&#xff0c;可以用定时重置端口的办法&#xff0c;调用接口 http://ip/usb_server/reset_port,参数为 {"port":"B5-1-2","vid_pid":"09…

视频监控业务平台LntonCVS视频监控管理平台智慧机场视频监控应用方案

随着人们生活水平的提高&#xff0c;对机场的需求日益增加。随之而来的是民航新建、迁建和扩建项目的激增&#xff0c;这些项目需要配备先进的安防监控系统&#xff0c;以满足民航机场安全管理和运营业务的迅速发展需求。 智慧机场主要涉及两个主要场景&#xff1a;候机厅和停机…

智慧城市的建设乃民之福音,建议普及这一技术

**智慧城市的建设乃民之福音&#xff0c;建议普及这一技术** 智慧城市已成为城市现代化的关键。智慧城市的建设不仅提高了城市管理的效率&#xff0c;还为市民带来了诸多便利。因此&#xff0c;我们应当积极推广并普及智慧城市技术&#xff0c;让这一福祉惠及更多民众。 如需…

SAP EWM display message对话框长度限制

1.问题 使用标准方法/scwm/cl_rf_dynpro_srvc=>display_message显示消息文本,由于消息文本过长而被截取,影响显示效果 2.解决 通过调试跟踪当前标准方法,发现屏幕显示长度为40,最多显示4行,且iv_msg_text把每一行显示字段用空格拼接起来,故以下代码需要把显示消息…

C# + halcon 联合编程示例

C# halcon 联合编程示例 实现功能 1.加载图像 2.画直线&#xff0c;画圆&#xff0c;画矩形, 画椭圆 ROI&#xff0c;可以调整大小和位置 3.实现找边&#xff0c;找圆功能 效果 开发环境 Visual Studio 2022 .NET Framework 4.8 halcondotnet.dll 查看帮助文档 项目结构 DL…

MT3056 交换序列

思路&#xff1a; 与题目 MT3055 交换排列 类似 代码&#xff1a; #include <bits/stdc.h> using namespace std; const int N 1e4 10; int n, fa[N], b[N], d[N]; void init(int n) {for (int i 1; i < n; i)fa[i] i; } int find(int x) {return x fa[x] ?…

在Visutal Studio 2022中完成D3D12初始化

在Visutal Studio 2022中完成DirectX设备初始化 1 DirectX121.1 DirectX 简介1.2 DirectX SDK安装2 D3D12初始化2.1 创建Windwos桌面项目2.2 修改符合模式2.3 下载d3dx12.h文件2.4 创建一个异常类D3DException,定义抛出异常实例的宏ThrowIfFailed3 D3D12的初始化步骤3.1 初始化…

聊一聊中小企业如何开展持续交付

持续交付的定义&#xff1a; 持续交付&#xff08;Continuous Delivery&#xff0c;简称CD&#xff09;是一种软件工程实践&#xff0c;旨在让软件产品的产出过程在一个短周期内完成&#xff0c;以保证软件可以稳定、持续地保持在随时可以发布的状况。它的核心目标在于加快软件…

C++函数调用运算符、函数调用对象和包装器详细介绍与总结

函数调用运算符 A.What&#xff08;函数对象&#xff09; 如果类定义了函数调用运算符&#xff0c;则该类的对象称为函数对象 B.Which&#xff08;有哪些可调用函数对象&#xff09; 函数 函数指针 lambd函数对象 bind创建的对象 重载了函数调用符的类对象 C.函数对象lambda l…

NVIDIA良心给显卡免费升级,只为挨更多的骂

起猛了&#xff0c;还真的以为 NVIDIA 良心发现了。 众所周知&#xff0c;英伟达对于咱们普通游戏玩家向来不屑一顾。只因为游戏业务在 NVIDIA 收入中占比较少。 在最新的 40 系显卡 RTX 4070 Ti Super 显卡中&#xff0c;NVIDIA悄悄给它来了一次核心「升级」&#xff0c;将原…

PLC数据采集网关的具体使用说明-天拓四方

PLC数据采集网关通过以太网、串口等通信接口与PLC设备连接&#xff0c;实现数据的实时采集。网关内置数据处理模块&#xff0c;可以对采集到的数据进行清洗、转换和存储&#xff0c;以满足不同应用场景的需求。同时&#xff0c;PLC数据采集网关支持多种通信协议&#xff0c;如M…

伦敦银看盘一般看什么 这3样东西不能缺少

伦敦银看盘&#xff0c;是指伦敦银市场开市之后&#xff0c;投资者打开走势图表&#xff0c;观察盘面行情和盘口信息的过程。一般来说&#xff0c;懂得看盘的人可能会被贴上专业的标签&#xff0c;我们在各种影视作品中看到&#xff0c;那些华尔街的交易员坐在电脑面前&#xf…

【密码学】大整数分解问题和离散对数问题

公钥密码体制的主要思想是通过一种非对称性&#xff0c;即正向计算简单&#xff0c;逆向计算复杂的加密算法设计&#xff0c;来解决安全通信。本文介绍两种在密码学领域内最为人所熟知、应用最为广泛的数学难题——大整数分解问题与离散对数问题 一、大整数分解问题 &#xf…

《算法笔记》总结No.6——贪心

一.简单贪心 贪心法是求解一类最优化问题的方法&#xff0c;它总是考虑在当前状态下局部最优(或较优)之后&#xff0c;来使全局的结果达到最优(或较优)的策略。显然&#xff0c;如果采取较优而非最优的策略(最优策略可能不存在或是不易想到)&#xff0c;得到的全局结果也无法是…