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

这篇具有很好参考价值的文章主要介绍了算法通过村第四关-栈黄金笔记|表达式问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言


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

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

1. 计算器问题

参考题目介绍:227. 基本计算器 II - 力扣(LeetCode)
算法通过村第四关-栈黄金笔记|表达式问题,算法集训营,算法,笔记,栈,数据结构,leetcode,逆波兰表达式,表达式问题
算法通过村第四关-栈黄金笔记|表达式问题,算法集训营,算法,笔记,栈,数据结构,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)
算法通过村第四关-栈黄金笔记|表达式问题,算法集训营,算法,笔记,栈,数据结构,leetcode,逆波兰表达式,表达式问题
算法通过村第四关-栈黄金笔记|表达式问题,算法集训营,算法,笔记,栈,数据结构,leetcode,逆波兰表达式,表达式问题
说实话这个题颇有难度,可以放在学习完二叉树再来看⭐⭐

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

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

🐟聪明讲个笑话:

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

算法通过村第四关-栈黄金笔记|表达式问题,算法集训营,算法,笔记,栈,数据结构,leetcode,逆波兰表达式,表达式问题
对应的三种表达式:

中缀表达式:( 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();
    }

总结

提示:栈的运用,表达式策略,逆波兰。文章来源地址https://www.toymoban.com/news/detail-689350.html

到了这里,关于算法通过村第四关-栈黄金笔记|表达式问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【代码随想录-Leetcode第四题:150. 逆波兰表达式求值】

    给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。 注意: 有效的算符为 ‘+’、‘-’、‘*’ 和 ‘/’ 。 每个操作数(运算对象)都可以是一个整数或者另一个表达式。 两个整数之间的除法总

    2024年02月13日
    浏览(31)
  • 小白到运维工程师自学之路 第四十九集 (正则表达式之grep)

    1、正则表达式(Regular Expression,简称为RegExp或Regex)是一种用于描述、匹配和操作文本的字符串模式的表达式。它提供了一种强大而灵活的方式来进行字符串的搜索、替换、提取和验证操作。 2、正则表达式可以用于各种编程语言和应用程序中,包括文本编辑器、命令行工具

    2024年02月13日
    浏览(37)
  • Golang通过栈实现表达式运算(中缀表达式转后缀表达式解析语法)

    需求背景:将string表达式数组 [title == AUSU ( header == Wecome || brand != AC68U )] 解析并使用ES查询得到运算结果。 分析:带有括号的表达式,需要根据优先级解析,可将中缀表达式转换为后缀表达式,去除括号

    2024年02月14日
    浏览(38)
  • 【sqli靶场】第四关和第五关通关思路

    目录 前言 一、sqli靶场第四关 1.1 判断注入类型 1.2 观察报错   1.3 判断数据表中的列数 1.4 使用union联合查询 1.5 使用group_concat()函数 二、sqli靶场第五关 2.1 判断注入类型 2.2 使用extractvalue函数报错 2.3 爆出数据库中的表名 2.4 爆出users表中的列名 2.5 爆出users表中的数据 🌈嗨

    2024年01月24日
    浏览(20)
  • java通过正则表达式提取信息

    工具类如下 使用以及结果 下面这个即为data的原文 结果 推荐这个网站,看起来更直观 正则在线 真正比较难的事儿吧,是怎么写这个正则表达式 有的表达式不是不能用,只是在java程序中不好用,怎么办呢,推荐用chatgpt吧,让他来帮你写表达式 第一步,先把文案发出去 第二

    2024年02月16日
    浏览(33)
  • Notepad++工具通过正则表达式批量替换内容

    Ctrl+H弹出小窗口;查找目标输入$,替换为输入特定字符串;选中循环查找,查找模式选正则表达式;最后点击全部替换 Ctrl+H弹出小窗口;查找目标输入^,替换为输入特定字符串;选中循环查找,查找模式选正则表达式;最后点击全部替换 Ctrl+H弹出小窗口;查找目标输入 相

    2024年02月15日
    浏览(91)
  • 【数据结构与算法】【12】前缀表达式、中缀表达式、后缀表达式

    什么是前缀表达式、中缀表达式、后缀表达式 前缀表达式、中缀表达式、后缀表达式,是通过树来存储和计算表达式的三种不同方式 以如下公式为例 ( a + ( b − c ) ) ∗ d ( a+(b-c) )*d ( a + ( b − c ) ) ∗ d 通过树来存储该公式,可以表示为 那么问题就来了,树只是一种抽象的数据

    2024年02月08日
    浏览(38)
  • Java通过Lambda表达式根据指定字段去除重复数据(集合去重)

    这里博主给大家封装好了一个工具类,里面有两个方法。 方法一:可以根据指定字段去除重复数据。 方法二:可以获取到重复的数据。 大家在使用过程中直接拷贝下方代码在要去重的类中调用即可。 导入这个工具类后怎么使用呢?我们接着往下看。 List rstList = list.stream()

    2024年02月16日
    浏览(33)
  • 【Python小技巧】通过实例说明推导式,条件表达式和Lambda函数

    按照国际惯例,首先声明:本文只是我自己学习的理解,虽然参考了他人的宝贵见解及成果,但是内容可能存在不准确的地方。如果发现文中错误,希望批评指正,共同进步。 本文总结在Python编程中会使用到的三个(高阶)小技巧:推导式,条件表达式和Lambda函数,并通过实

    2024年03月27日
    浏览(43)
  • 学习笔记-正则表达式

    https://www.runoob.com/regexp/regexp-tutorial.html 正则表达式re(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为\\\"元字符\\\"),可以用来描述和匹配字符串的特定模式。 个人理解,re是对字符序列进行建模,建立多对一映射,能够覆盖所有字符

    2024年02月09日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包