算法通过村第四关-栈黄金笔记|表达式问题

news2024/11/30 12:43:32

文章目录

  • 前言
    • 1. 计算器问题
    • 2. 逆波兰表达式问题
  • 总结


前言


提示:快乐的人没有过去,不快乐的人除了过去一无所有。 --理查德·弗兰纳根《深入北方的小路》

栈的进阶来了,还记得栈的使用场景吗?表达式和符号,这不就来了

1. 计算器问题

参考题目介绍:227. 基本计算器 II - 力扣(LeetCode)
在这里插入图片描述
在这里插入图片描述
计算问题在栈的运用也是非常广泛的。在乘除优先于加减计算,我们需要考虑所有的乘除运算,并将这些乘除运算后的整数放回原来对应的表达式中,随后整个表达式的值等于一系列整数加减后的运算值。

基于这样的想法,我们可以使用的们的老朋友栈了,保存这些(进行乘除运算后的)整数值。对于加减后的数字,将其直接压入栈中,对于乘除后的数字,我可以直接与栈顶元素计算,并替换栈顶元素作为计算后的结果。

具体来说,我们遍历字符串s,并用变量preSign来记录每个数字之前的运算符,对于第一个数字,其之前的运算符视为加号。每次遍历到数组的末尾时,根据preSign来决定计算方式

  • 加号:将数字压入栈中
  • 减号:将数字的相反数压入栈中
  • 乘除号:计算数字与栈顶元素,并将栈顶元素替换为计算结果。

代码实现中,读到一个运算符,或者遍历到字符串末尾,,就认为遍历到了数字末尾。处理完该数字后,更新preSign为当前遍历的字符。遍历完字符串s后,将栈中的元素累加,即为该表达式的结果。

	 /**
     * 实现计算器问题
     * @param s
     * @return
     */
    public static int calculate(String s) {
        Deque<Integer> stack = new ArrayDeque<Integer>();
        // 计算可以都看做时 +   这里是前一个符号
        Character preSign = '+';
        int num = 0;
        int n = s.length();
        for (int i = 0; i < n; i++) {
            if (Character.isDigit(s.charAt(i))) {
                // 字符转数字  考虑到大于10 的情况
                num = num * 10 + s.charAt(i) - '0';
            }
            if (!Character.isDigit(s.charAt(i)) && s.charAt(i) != ' ' || i == n - 1) {
                switch (preSign) {
                    case '+':
                        stack.push(num);
                        break;
                    case '-':
                        stack.push(-num);
                        break;
                    case '*': // 5 * 2
                        stack.push(stack.pop() * num);
                        break;
                    case '/':  // 10 / 2
                        stack.push(stack.pop() / num);
                        break;
                    default:
                        break;
                }
                // 更新前一个符号   这样就可以确定乘除优先了
                preSign = s.charAt(i);
                num = 0;
            }
        }
        int ans = 0;
        while(!stack.isEmpty()){
            ans += stack.pop();
        }
        return ans;
    }

注意:

  • perSign 指的是前一个运算符号(首次默认看作是+号)

  • 慢一次计算 就可以确保乘除优先了

2. 逆波兰表达式问题

参考题目介绍:150. 逆波兰表达式求值 - 力扣(LeetCode)
在这里插入图片描述
在这里插入图片描述
说实话这个题颇有难度,可以放在学习完二叉树再来看⭐⭐

表达式计算式编译原理,自然语言处理,文本分析等领域非常看重的问题,这里我们就挑这个题目练手,逆波兰表达式。

这道题看似困难,实则真困难呐,你要是不知道什么是表达式,完了,你不会了。这里的表达式就好比一起上小学学的(2+1)* 3这样字的,根据不同的记法,就有前缀,中缀,后缀之说,区别呢在于运算符号相对于操作数的位置,前缀就是运算符号在操作数前面,那后缀和中缀呢?你想想?

🐟聪明讲个笑话:

有一天,一只蚂蚁遇到了一只蜗牛。蚂蚁问蜗牛:“为什么我们走路的时候总是把头抬得那么高?”蜗牛回答:“因为我们的目标在地上。”

在这里插入图片描述
对应的三种表达式:

中缀表达式:( 1 + 2* 3
前缀表达式: + 1 2 * 3
后缀表达式: 1 2 + 3 *

从上面看,中缀的表达式更像是我们常见的,它作为一种通用的算数运算和逻辑公式表示,操作符以中缀形式处于操作数的中间。虽然我们的大脑很容易就可以理解这些分析最终拿到结果,但是对于计算机来说,就很头疼了,计算机在做表达式计算的时候,通常是需要将中缀表达式转换为前缀或者后缀表达式再进行求值的。前缀表达式的运算符位于两个相应操作数之前,前缀表达式又被称为前缀记法或者波兰是,而后缀表达式就是你波兰式了。

观察后我们就可以看出,根据特点将数字保存下来,遇到符号就计算。比如:1 2 + 3 * 遇到+ ,我们就好1 和 2 加起来,得到结果 3 然后在进行计算 得到结果 9 .

这样得话之不是容易一些,遇到数字就进栈,遇到运算符就取出栈中的最上面的两个元素进行计算,最后再将结果入栈。实现代码会不会简单一些:

public class EvalRPN {
    public static int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<Integer>();
        for (String token : tokens) {
            if (!Character.isDigit(token.charAt(0)) && token.length() == 1) {
                // 取出栈顶的数字
                int a = stack.pop();
                int b = stack.pop();
                // 做运算
                switch (token) {
                    case "+":   // a b +
                        stack.push(a + b);
                        break;
                    case "-": // a b -
                        stack.push(a - b);
                        break;
                    case "*": // a b *
                        stack.push(a * b);
                        break;
                    case "/": // a b /
                        stack.push(a / b);
                        break;
                    default:
                        break;
                }
            }else {
                // 直接存入栈中
                stack.push(Integer.parseInt(token));
            }
        }
        return  stack.pop();
    }

总结

提示:栈的运用,表达式策略,逆波兰。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

杂记 23.8.30

目录 tesol专业介绍 EMBA项目 适合学习时候听的轻音乐 安全感和孤独感 puffy fix sb up with sth For all the world Size up 博雅、博雅教育 人是需要被仰视的 tesol专业介绍 tesol专业的全称是“Teaching English to Speakers of Other Language”&#xff0c;可译…

自动化管理管理工具----Ansible

目录 ​编辑 一、Ansible概念 1.1特点 二、工作机制&#xff08;日常模块&#xff09; 2.1 核心程序 三、Ansible 环境安装部署 四、ansible 命令行模块 4.1command 模块 4.2shell 模块 4.3cron 模块 4.4user 模块 4.5group 模块 4.6copy模块 4.7file模块 4.8ho…

支持AI视频处理的高容量流媒体加速卡方案

// 编者按&#xff1a; 实况直播业务随着流媒体市场的发展增长迅速。与传统流媒体“一对多”的模式不同&#xff0c;直播流媒体高交互的特性和 “多对多”的架构对时延的要求越来越高&#xff0c;传统基础设施部署和硬件已经不能高效处理这类需求。在此背景下&#xff0c;AMD…

ELK日志收集系统(四十九)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、概述 二、组件 1. elasticsearch 2. logstash 2.1 工作过程 2.2 INPUT 2.3 FILETER 2.4 OUTPUTS 3. kibana 三、架构类型 3.1 ELK 3.2 ELKK 3.3 ELFK 3.5 EF…

科技政策 | 浙江省科学技术厅关于组织申报2024年度“尖兵”“领雁”研发攻关计划第一批项目的通知

原创 | 文 BFT机器人 近日浙江省科技厅发布了2024年第一批“尖兵”“领雁”研发攻关计划&#xff1b;2024年度攻关计划将围绕三大科创高地战略领域&#xff0c;聚焦研发具有先发优势的关键共性技术和引领未来发展的基础前沿技术&#xff0c;根据战略需求、规划需求、市场需求等…

MySQL之从单机到集群

写在前面 本文一起看下MySQL是单机存在的问题&#xff0c;以及为了解决这些问题所提出的各种解决方案。 1&#xff1a;从单机到集群 并非业务发展初期我们就直接使用集群来支撑业务&#xff0c;而是简单的使用单机版本&#xff0c;但是随着业务的发展&#xff0c;单机的各种…

22 Linux高级篇-定制自己的Linux系统

22 Linux高级篇-定制自己的Linux系统 文章目录 22 Linux高级篇-定制自己的Linux系统22.1 Linux7启动流程介绍22.1.1 Linux7启动流程22.1.3 systemd概述 22.2 *制作min-linux思路分析22.3 操作步骤步骤1&#xff1a;创建新磁盘步骤2&#xff1a;制作启动盘步骤3&#xff1a;创建…

一个简单的vim例子

一.欢迎来到我的酒馆 在本章节介绍vim工具。 目录 一.欢迎来到我的酒馆二.什么是vim 二.什么是vim 2.1什么是vim vim是一种Linux命令行类型 的文本编辑器。vim指的是"vi improved"&#xff0c;意思是vi工具的升级版。vim是基于vi实现的&#xff0c;它提供了…

设计模式--模板方法模式(Template Method Pattern)

一、什么是模板方法模式&#xff08;Template Method Pattern&#xff09; 模板方法模式&#xff08;Template Method Pattern&#xff09;是一种行为型设计模式&#xff0c;它定义了一个算法的骨架&#xff0c;将一些步骤的实现延迟到子类中。模板方法模式允许在不改变算法的…

视频汇聚/视频云存储/视频监控管理平台EasyCVR新增首次登录强制修改密码

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。视频汇聚平台既具…

Quartus II安装下载驱动

Quartus II安装下载驱动 安装步骤&#xff1a; &#xff08;1&#xff09;安装完quartus后会自带USB-Blaster的驱动程序&#xff0c;因此不用再去网上下载。 &#xff08;2&#xff09;右键点脑左下角win&#xff0c;找到设备管理器并进入。 &#xff08;3&#xff09;找到…

QT 常用类与组件

0 思维导图 1 信息调试类&#xff08;QDebug&#xff09; #include "widget.h" #include<iostream> //printf #include<QDebug> //qDebuf using namespace std; //coutWidget::Widget(QWidget *parent): QWidget(parent) {//输出函数//使用…

【python爬虫】—图片爬取

图片爬取 需求分析Python实现 需求分析 从https://pic.netbian.com/4kfengjing/网站爬取图片&#xff0c;并保存 Python实现 获取待爬取网页 def get_htmls(pageslist(range(2, 5))):"""获取待爬取网页"""pages_list []for page in pages:u…

[Pandas] 求百分比并添加百分(%)号

导入数据 import pandas as pddf pd.DataFrame(data{orders: [2130,5102,3256,1297,1918,786],repeat_orders: [73,158,89,30,49,18]}) df df[repetition_rate] df[repeat_orders] / df[orders] df df[repetition_rate] df[repetition_rate].apply(lambda x: format(x, .2…

哈希表+字符串

一)知识回顾: 1)哈希表是什么?哈希表是存储数据的容器 2)哈希表有啥用?快速的查找某一个元素 3)什么时候使用哈希表?频繁的查找某一个数的时候&#xff0c;当我们快速查找某一个数的时候&#xff0c;不光要想到哈希表还需要想到二分查找&#xff0c;但是二分查找算法的局限性…

Linux——(第二章)Linux的目录结构

VMwear workstations下载及安装 Ubuntu server 18.04安装 VScode下载与安装 使用VS Code连接远程服务器 MobaXterm的下载安装及远程连接 Filezila的下载、安装与使用&#xff08;向服务器传输文件&#xff09; 目录 1.基本介绍 2.Linux目录结构 3.具体目录说明 4.补充 1.基…

从编程语言的角度来理解正则表达式

程序代码是对现实事物处理逻辑的抽象&#xff0c;而正则表达式&#xff0c;则是对复杂的字符匹配程序代码的进一步抽象&#xff1b;也就是说&#xff0c;高度简洁的正则表达式&#xff0c;可以认为其背后所对应的&#xff0c;是字符匹配程序代码&#xff0c;而字符匹配程序代码…

低代码:工业互联网从“学步”到“奔跑”的加速器

一、政策、技术合力推进&#xff0c;工业互联网发展提速 工业制造业曾经创造了我国的崛起神话&#xff0c;最近几年&#xff0c;随着新闻中一些老牌制造业厂商的闭幕&#xff0c;很多人都开始思考&#xff1a;未来工业会是什么样子&#xff1f; 放眼全球&#xff0c;各国对于工…

阿里云轻量应用服务器Linux-Centos7下Oracle19c的安装

初始环境&#xff1a;阿里云轻量应用服务器已经重置系统为CentOS7.3-64位 具体目标&#xff1a;安装Oracle Database 19c 目录 第一步&#xff1a;检查Linux系统版本第二步&#xff1a;下载Oracle19c的安装包第三步&#xff1a;下载Oracle19c的预安装包第四步&#xff1a;上传到…