【力扣刷题】数组实现栈、后缀表达式(逆波兰表达式)求值、中缀表达式转换为后缀表达式(无括号有括号)

news2024/11/17 17:44:52

在这里插入图片描述

🐌个人主页: 🐌 叶落闲庭
💨我的专栏:💨
c语言
数据结构
javaEE
操作系统
Redis

石可破也,而不可夺坚;丹可磨也,而不可夺赤。


刷题篇

  • 一、数组实现栈
    • 1.1 题目描述
    • 1.2 思路分析
    • 1.3 代码演示
  • 二、 后缀表达式(逆波兰表达式)求值
    • 2.1 题目描述
    • 2.2 思路分析
    • 2.3 代码演示
  • 三、中缀表达式转换为后缀表达式(无括号)
    • 3.1 题目描述
    • 3.2 思路分析
    • 3.3 代码演示
  • 四、中缀表达式转换为后缀表达式(有括号)
    • 4.1 题目描述
    • 4.2 思路分析
    • 4.3 代码演示

一、数组实现栈

1.1 题目描述

给定一个栈的接口,实现该接口中的方法,接口中的方法包括向栈顶添加元素、从栈顶弹出元素、返回栈顶元素,不弹出、判断栈是否为空、判断栈是否已满,要求使用数组实现。

  • 要实现的栈的接口:
public interface Stack<E> {
    /**
     * 向栈顶添加元素
     * @param value -带压入值
     * @return  -成功返回true,失败返回false
     */
    boolean push(E value);

    /**
     * 从栈顶弹出元素
     * @return -栈非空返回栈顶元素,栈为空返回null
     */
    E pop();

    /**
     * 返回栈顶元素,不弹出
     * @return -栈非空返回栈顶元素,栈为空返回null
     */
    E peak();

    /**
     * 判断栈是否为空
     * @return -空返回true,非空返回false
     */
    boolean isEmpty();

    /**
     * 判断栈是否已满
     * @return -满返回true,不满返回false
     */
    boolean isFull();
}

1.2 思路分析

用数组来实现栈的方法相对比较简单,首先定义一个数组,用来模拟栈的功能,定义一个整型变量作为栈顶指针(int top),为这个数组栈定义一个带形参的构造方法,参数表示数组的默认长度(int capacity),即栈的容量。
可以将栈顶指针表示的索引值与数组长度相等时作为判定栈是否满的标志,即当top == array.length()时表示栈已满,当top == 0时表示栈为空。
压栈操作就是将要添加的值添加到数组索引为top的位置处,即向栈顶添加元素,然后top指向top+1索引处,当栈为满时,返回false表示添加失败。
出栈操作先判断栈是否为空,若栈为空,则直接返回false表示没有元素,否则拿到此时栈顶的元素,注意top表示的是下一个栈顶元素存放的位置,所以此时的栈顶元素的索引是top-1,返回数组下标为top-1的元素的值,然后top–表示失去一个元素
拿到栈顶元素且不弹出与出栈类似,不同的是,拿到栈顶元素且不弹出不需要将top自减,只需返回数组下标为top-1的元素的值即可。

1.3 代码演示

public class ArrayStack<E> implements Stack<E>,Iterable<E> {
    private E[] array;
    private int top;    //栈顶指针

    @SuppressWarnings("all")
    public ArrayStack(int capacity) {
        this.array = (E[]) new Object[capacity];
    }

    @Override
    public boolean push(E value) {
        if (isFull()) {
            return false;
        }
        array[top] = value;
        top++;
        return true;
    }

    @Override
    public E pop() {
        if (isEmpty()) {
            return null;
        }
        //找到栈顶元素
        E value = array[top - 1];
        top--;
        return value;
    }

    @Override
    public E peak() {
        if (isEmpty()) {
            return null;
        }
        //找到栈顶元素
        E value = array[top - 1];
        return value;
    }

    @Override
    public boolean isEmpty() {
        return top == 0;
    }

    @Override
    public boolean isFull() {
        return top == array.length;
    }

    @Override
    public Iterator<E> iterator() {
        return new Iterator<E>() {
            int p = top;
            @Override
            public boolean hasNext() {
                return p > 0;
            }

            @Override
            public E next() {
                E value = array[--p];
                return value;
            }
        };
    }
}

二、 后缀表达式(逆波兰表达式)求值

2.1 题目描述

给定一个字符串数组,这串数组是后缀表达式形式(这种表示方式把运算符写在运算对象的后面,例如,把a+b写成ab+,所以也称为后缀式。这种表示法的优点是根据运算对象和算符的出现次序进行计算,不需要使用括号,也便于用械实现求值。),要求通过代码将这串表达式的值计算出来,不需要考虑表达式的正确性,默认表达式一定有值。

2.2 思路分析

利用栈的特性对这个字符串数组进行遍历,通过对遍历到的每个元素进行判断,当遍历到的元素不是运算符时,表示这个元素是字符串类型的数字,将它转换为整型的数字并添加到栈中,当遍历到的元素是运算符时,则从栈顶弹出两个元素,并进行该运算符的计算,将计算得到的结果再次添加到栈中,当整个数组遍历完时,此时栈顶的元素就是最终的结果,直接返回栈顶元素。

2.3 代码演示

    public int evalRPN(String[] tokens) {
        LinkedList<Integer> stack = new LinkedList<>();
        for (String token : tokens) {
            switch (token) {
                case "+" : {
                    Integer b = stack.pop();
                    Integer a = stack.pop();
                    stack.push(a + b);
                    break;
                }
                case "-" : {
                    Integer b = stack.pop();
                    Integer a = stack.pop();
                    stack.push(a - b);
                    break;
                }
                case "*" : {
                    Integer b = stack.pop();
                    Integer a = stack.pop();
                    stack.push(a * b);
                    break;
                }
                case "/" : {
                    Integer b = stack.pop();
                    Integer a = stack.pop();
                    stack.push(a / b);
                    break;
                }
                default: { //数字
                    stack.push(Integer.parseInt(token));
                    break;
                }
            }
        }
        return stack.pop();
    }

三、中缀表达式转换为后缀表达式(无括号)

3.1 题目描述

给定一段字符串,该字符串是一段标准的中缀表达式(如a + b - c、a * b + d、a + b * c - d等),要求将该式转换为后缀表达式。

3.2 思路分析

利用栈的特性,在遍历字符串时每次得到一个字符,设置一个优先级判断,若这个字符是数字的话,直接将它拼接在将要返回的新字符串上,若这个字符是运算符,则先判断栈是否为空,当栈为空时,直接将该字符添加到栈中,若栈不为空,则比较当前运算符与栈顶运算符的优先级大小,若当前运算符的优先级大,则直接将该字符添加到栈中,若当前运算符优先级小,则需要先将栈中比当前运算符优先级小的全部弹出并拼接到之前的字符串中,然后再将当前运算符添加到栈中,当遍历完字符串并且栈不为空时,将栈中剩余的字符串弹出并拼接到字符串,最后返回最终的字符串。

3.3 代码演示

    static String infixToSuffix(String exp) {
        LinkedList<Character> stack = new LinkedList<>();
        StringBuilder sb = new StringBuilder(exp.length());
        /**
         * 1.遇到非运算符 直接拼串
         * 2.遇到 + - * /
         *  - 它的优先级比栈顶运算符优先级高,入栈
         *  - 否则把栈里优先级 >= 它 的都出栈,它再入栈
         * 3.遍历完成,栈里剩余运算符依次出栈
         */
        for (int i = 0; i < exp.length(); i++) {
            char c = exp.charAt(i);
            switch (c) {
                case '+':
                case '-':
                case '*':
                case '/': {
                    //比较运算符优先级
                    //栈为空,直接将当前运算符压入栈中
                    if (stack.isEmpty()) {
                        stack.push(c);
                    } else {
                        if (priority(c) > priority(stack.peek())) {
                            stack.push(c);
                        } else {
                            while (!stack.isEmpty() && priority(c) <= priority(stack.peek())) {
                                sb.append(stack.pop());
                            }
                            stack.push(c);
                        }
                    }
                    break;
                }
                default: {
                    //直接拼串
                    sb.append(c);
                    break;
                }
            }
        }
        while (!stack.isEmpty()) {
            sb.append(stack.pop());
        }
        return sb.toString();
    }

    public static int priority(char c) {
        int p = 0;
        switch(c) {
            case '*':
            case '/': {
                p = 2;
                break;
            }
            case '+':
            case '-': {
                p = 1;
                break;
            } default: {
                throw new IllegalArgumentException("不合法的符号:“" + c + "“");
            }
        };
        return p;
    }

四、中缀表达式转换为后缀表达式(有括号)

4.1 题目描述

给定一段字符串,该字符串是一段标准的中缀表达式,并且这些中缀表达式中带有括号(如:(a + b) * c、(a + b * c - d) * e、(a * b)+c),要求将该式转换为后缀表达式。

4.2 思路分析

与无括号的中缀转后缀类似,只不过多了一个左括号的优先级判断,在无括号的基础上,为左括号添加一个更低的优先级,在遍历字符串时,若遇到左括号,则直接将其添加到栈中,栈中的字符(数字或运算符)判断方法不变,若遇到右括号,则将栈中从栈顶到左括号为止(不包含左括号)的所有字符弹出并拼接到最终要返回字符串,然后再将左括号弹出(这样做的目的是不拼接左括号),之后的步骤与无括号的相同,当遍历完字符串并且栈不为空时,将栈中剩余的字符串弹出并拼接到字符串,最后返回最终的字符串。

4.3 代码演示

    static String infixToSuffix(String exp) {
        LinkedList<Character> stack = new LinkedList<>();
        StringBuilder sb = new StringBuilder(exp.length());
        /**
         * 1.遇到非运算符 直接拼串
         * 2.遇到 + - * /
         *  - 它的优先级比栈顶运算符优先级高,入栈
         *  - 否则把栈里优先级 >= 它 的都出栈,它再入栈
         * 3.遍历完成,栈里剩余运算符依次出栈
         * 4.带()
         *  - 左括号直接入栈,左括号优先级设置为0
         *  - 右括号就把栈里的栈顶到左括号为止的所有运算符出栈
         */
        for (int i = 0; i < exp.length(); i++) {
            char c = exp.charAt(i);
            switch (c) {
                case '+':
                case '-':
                case '*':
                case '/': {
                    //比较运算符优先级
                    //栈为空,直接将当前运算符压入栈中
                    if (stack.isEmpty()) {
                        stack.push(c);
                    } else {
                        if (priority(c)>priority(stack.peek())) {
                            stack.push(c);
                        } else {
                            while (!stack.isEmpty() && priority(c) <= priority(stack.peek())) {
                                sb.append(stack.pop());
                            }
                            stack.push(c);
                        }
                    }
                    break;
                }
                case '(' : {
                    stack.push(c);
                    break;
                }
                case ')' : {
                    while (!stack.isEmpty() && stack.peek() != '(') {
                        sb.append(stack.pop());
                    }
                    stack.pop();
                    break;
                }
                default: {
                    //直接拼串
                    sb.append(c);
                    break;
                }
            }
        }
        while (!stack.isEmpty()) {
            sb.append(stack.pop());
        }
        return sb.toString();
    }

    public static int priority(char c) {
        int p = 0;
        switch(c) {
            case '*':
            case '/': {
                p = 2;
                break;
            }
            case '+':
            case '-': {
                p = 1;
                break;
            }
            case '(' : {
                p = 0;
                break;
            }
            default: {
                throw new IllegalArgumentException("不合法的符号:“" + c + "“");
            }
        };
        return p;
    }

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

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

相关文章

[补题记录] Atcoder Beginner Contest 293(E)

URL&#xff1a;https://atcoder.jp/contests/abc293 目录 E Problem/题意 Thought/思路 Code/代码 E Problem/题意 给出 A、X、M&#xff0c;求 。 Thought/思路 一开始想等比数列求和&#xff0c;但是 m 不保证是质数&#xff0c;所以不能用。 假设 dp[x] 表示&…

SpringMVC(第一个项目HelloWorld))

文章目录 1.在maven引入依赖2.配置web.xml3.创建请求控制器4.创建springMVC的配置文件5.测试HelloWorld总结 1.在maven引入依赖 <dependencies><!-- SpringMVC --><dependency><groupId>org.springframework</groupId><artifactId>spring…

linux minicom 调试串口

1、使用方法 1. 打开终端 2. 输入命令&#xff1a;minicom -D /dev/ttyS0 3. 按下回车键&#xff0c;进入minicom终端界面 4. 在终端界面中发送指令或数据&#xff0c;查看设备返回的数据 5. 按下CtrlA&#xff0c;松开释放&#xff0c;再按下X&#xff0c;退出minicom2、一些…

教你如何打造一款流行的服装定制小程序

随着移动互联网时代的到来&#xff0c;线上商务发展迅猛&#xff0c;服装店也开始积极探索线上销售渠道。其中&#xff0c;小程序成为了服装店主们的首选之一。小程序以其便捷、快速的特点&#xff0c;为服装店的线上经营带来了全新的机遇。接下来&#xff0c;我们将介绍如何通…

TCP和UDP的原理及其区别(三次握手、四次挥手)

TCP和UDP都是在传输层上工作的协议&#xff0c;用于在网络中传输数据。 1、TCP和UDP之间的区别 TCP和UDP的主要区别在于它们提供的服务和特性。TCP提供可靠的、有序的、基于连接的数据传输&#xff0c;适用于对数据完整性和可靠性要求较高的应用&#xff08;邮件、短信&#xf…

CPU飙高问题排查命令

1. 远程客户端连接服务器,top命令查看cpu占用最高的进程id 2. (top -H -p 进程pid) 命令: 找出进程里面线程占用CPU高的线程有哪些 ? 3. (printf 0x%x\n 线程id) 线程id转16进制 4. (./jstack PID | grep TID(十六进制) -A 30)

小县城蔬菜配送小程序制作全攻略

随着互联网的普及和人们对生活品质要求的提高&#xff0c;越来越多的小县城开始开发蔬菜配送小程序&#xff0c;以满足当地居民对新鲜蔬菜的需求。制作一个小县城蔬菜配送小程序&#xff0c;需要经过以下步骤&#xff1a; 步骤一&#xff1a;登录乔拓云平台 首先&#xff0c;打…

2023-10-19 LeetCode每日一题(同积元组)

2023-10-19每日一题 一、题目编号 1726. 同积元组二、题目链接 点击跳转到题目位置 三、题目描述 给你一个由 不同 正整数组成的数组 nums &#xff0c;请你返回满足 a * b c * d 的元组 (a, b, c, d) 的数量。其中 a、b、c 和 d 都是 nums 中的元素&#xff0c;且 a ! b…

博客系统测试报告

一、项目背景 本项目是一个简单的博客系统&#xff0c;该系统具有注册、登录、编写博客、修改博客、删除博客、浏览博客的功能。 项目地址&#xff1a;博客列表http://59.110.22.4:9011/blog_list.html 二、项目功能 1、注册功能&#xff1a;用户可以创建适当的用户名、密码…

JavaWeb——IDEA相关配置(Tomcat安装)

3、Tomcat 3.1、Tomcat安装 可以在国内一些镜像网站中下载Tomcat&#xff0c;同样也可以在[Tomcat官网](Apache Tomcat - Welcome!)下载 3.2、Tomcat启动和配置 一些文件夹的说明 启动&#xff0c;关闭Tomcat 启动&#xff1a;Tomcat文件夹→bin→startup.bat 关闭&#…

博客自动化测试

1、熟悉项目 2、针对核心流程设计测试用例&#xff08;手工测试用例&#xff09; 3、将手工测试用例转化成自动化测试用例 4、部署 1、熟悉项目 2、针对核心流程设计测试用例&#xff08;手工测试用例&#xff09; 3、将手工测试用例转化成自动化测试用例 代码结构如何设…

【微信小程序开发】小程序微信用户授权登录(用户信息手机号)

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于小程序的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 授权流程讲解 一.用户信息授权登录 1.w…

基于springboot小区物业管理系统

功能如下图所示 摘要 基于Spring Boot的小区物业管理系统是一项重要的解决方案&#xff0c;旨在提升小区物业管理的效率和质量。这个系统整合了现代技术和管理实践&#xff0c;为小区内的住户和物业管理人员提供了便捷的工具&#xff0c;以更好地管理和维护住宅区。该系统的关键…

10_集成学习方法:随机森林、Boosting

文章目录 1 集成学习&#xff08;Ensemble Learning)1.1 集成学习1.2 Why need Ensemble Learning?1.3 Bagging方法 2 随机森林(Random Forest)2.1 随机森林的优点2.2 随机森林算法案例2.3 随机森林的思考&#xff08;--->提升学习&#xff09; 3 随机森林&#xff08;RF&a…

【RNA biology】RNA的多功能性与早期生命进化

文章目录 RNARNA plays core functions in Central Dogma of BiologyrRNAsnRNA RNA worldReplication催化作用感知环境变化并作出响应 来自Manolis Kellis教授&#xff08;MIT计算生物学主任&#xff09;的课 油管链接&#xff1a;6.047/6.878 Lecture 7 - RNA folding, RNA wo…

PHP代码审计工具

PHP代码审计工具 1 环境准备 Seay源代码审计系统.exe 和准备靶场的源码php 2 Seay下载地址 https://github.com/f1tz/cnseay安装Seay源代码审计系统.exe报错时&#xff0c;安装.net framework 3.5 # windows插件.net framework 3.5 下砸地址 https://www.microsoft.com/en…

CSS基础入门01

目录 1.CSS是什么 2.基本语法规范 3.引入方式 3.1内部样式表 3.2行内样式表 3.3外部样式 4.代码风格 4.1样式格式 4.2样式大小写 4.3空格规范 5.选择器 5.1选择器的功能 5.2选择器的种类 6.基础选择器 6.1标签选择器 6.2类选择器 6.3id 选择器 6.4通配符选择…

【趣味随笔】盘点那些国内外知名的扫地机器人品牌

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

电容屏物体识别手工制作

电容屏识别物体效果2 电容屏识别物体效果1 电容屏识别物体效果3 电容屏识别物体效果4 电容识别物理效果5 我们感兴趣的是找到让我们的平面屏幕与物理三维物体和表面交互的方法。 触摸屏无处不在&#xff0c;成千上万的应用程序中有多种设备和屏幕格式&#xff0c;但我们只找到…

十三水中各种牌型判断LUA版

近期回归程序行业&#xff0c;由于业务需求需要做十三水游戏&#xff0c;什么是十三水就不在多讲&#xff0c;下面是判断十三水牌型的方法&#xff08;带大小王&#xff09; GetSSSPaiType {}; local this GetSSSPaiType; local huaseTable {}; local numTable {}; functi…