栈的应用-综合计数器的实现

2023-10-27

目录

前言

一、思路分析

二、代码实现

总结

前言

在实现综合计数器之前,大家应该先了解一下什么是前中后缀表达式

前缀、中缀和后缀表达式是表示数学表达式的三种不同方式。

  1. 前缀表达式(也称为波兰式或前缀记法):操作符位于操作数之前。例如,"+ 2 3"表示加法操作,其中2和3是操作数。

  2. 中缀表达式:操作符位于操作数之间。这是我们通常使用的数学表达式表示方式。例如,"2 + 3"表示加法操作,其中2和3是操作数。

  3. 后缀表达式(也称为逆波兰式或后缀记法):操作符位于操作数之后。例如,"2 3 +"表示加法操作,其中2和3是操作数。

这三种表达式都可以表示相同的数学运算,只是操作符和操作数的排列顺序不同。在计算机中,后缀表达式常用于数学表达式的求值,因为它可以通过使用栈来进行简单而高效的计算。

本次实现综合计算器就是借助后缀表达式来实现,为了简单起见,我们并不加入()等的符号


一、思路分析

定义两个栈,一个栈为数栈(NumStack)用来存放数字,另一个栈为符号栈,用来存放符号

1. 通过一个 index  值(索引),来遍历我们的表达式

2. 如果我们发现是一个数字, 就直接入数栈

3. 如果发现扫描到是一个符号,  就分如下情况

  3.1 如果发现当前的符号栈为 空,就直接入栈

  3.2 如果符号栈有操作符,就进行比较,果当前的操作符的优先级小于或者等于栈中的操作符, 就需要从数栈中pop出两个数,在从符号栈中pop出一个符号,进行运算,将得到结果,入数栈,然后将当前的操作符入符号栈, 果当前的操作符的优先级大于栈中的操作符, 就直接入符号栈.

4. 当表达式扫描完毕,就顺序的从 数栈和符号栈中pop出相应的数和符号,并运行.

5. 最后在数栈只有一个数字,就是表达式的结果

我们来举个例子 图解 计算 7*2*2-5+1 = 24

二、代码实现

代码量太大,不可能一步一步解析了,上面的过程如果能看懂,并且编程有一定基础,下面代码应该不成问题,代码出处033_尚硅谷_栈实现综合计算器-思路分析(1)_哔哩哔哩_bilibili

大家可以去看看

package 逆波兰计数器;

import StackDemo.StackEmptyException;

import java.util.Arrays;
import java.util.Scanner;

class Test{
    public static void main(String[] args) {
        String str = "7*2*2-5+1";
        ArrayStack numStack = new ArrayStack(10);
        ArrayStack operaStack = new ArrayStack(10);
        String s = "";
        int nums1 = 0;
        int nums2 = 0;
        int index = 0;
        int opera = 0;
        char ch = ' ';
        while (true) {
            ch = str.charAt(index);
            // 判断该字符是否是符号
            if(operaStack.isOpera(ch)){
                // 判断符号栈是否为空
                if(!operaStack.isEmpty()){
                    // 判断优先级
                    if(operaStack.priority(ch) <= operaStack.priority(operaStack.peek())){
                        nums1 = numStack.pop();
                        nums2 = numStack.pop();
                        opera = operaStack.pop();
                        int cal = numStack.cal(nums1, nums2, opera);
                        numStack.push(cal);
                        operaStack.push(ch);
                    }else{
                        operaStack.push(ch);
                    }
                }else{
                    // 符号栈为空,直接入栈
                    operaStack.push(ch);
                }
            }else{
                boolean flag = true;// 定义标志位 检查字符串是否达到末尾

                // 处理非个位数的情况 如 88 66 这样的数
                while (!operaStack.isOpera(ch)) {
                    s+=ch;
                    if(index == str.length() -1 ){
                        numStack.push(Integer.parseInt(s));
                        flag = false;
                        break;
                    }else {
                        index++;
                        ch = str.charAt(index);
                    }
                }
                if(!flag){
                    break;
                }
                numStack.push(Integer.parseInt(s));
                s = "";
                index--;
            }
            index++;
            if(index>=str.length()){
                break;
            }
        }

        while (true) {
            if(operaStack.isEmpty()){
                System.out.println(str+"="+numStack.pop());
                break;
            }
            nums1 = numStack.pop();
            nums2 = numStack.pop();
            opera = operaStack.pop();
            int cal = numStack.cal(nums1, nums2, opera);
            numStack.push(cal);
        }
    }

}



public class ArrayStack {
    private final int capacity;
    private int top = -1;
    private int[] stack ;

    public ArrayStack(int capacity){
        this.capacity = capacity;
        stack = new int[capacity];
    }

    // 入栈
    public void push(int data){
        if(isFull()){
            stack = Arrays.copyOf(stack,capacity*2);
        }
        top++;
        stack[top] = data;
    }

    // 出栈
    public int pop(){
        if(isEmpty()){
            throw new StackEmptyException("队列为空,无法删除元素");
        }

        int value = stack[top];
        top--;
        return value;
    }

    // 查看栈顶的值
    public int peek(){
        return stack[top];
    }

    // 制定优先级规则
    public int priority(int opera){
        if(opera == '*' || opera == '/'){
            return 1;
        }else if(opera == '+' || opera == '-'){
            return 0;
        }else{
            return -1;
        }
    }


    // 判断是否为运算符
    public boolean isOpera(int val){
        return val == '+' || val == '-' || val == '*' || val == '/';
    }

    // 运算方法
    public int cal(int num1,int num2,int opera){
        return  switch (opera) {
            case '+' -> num1 + num2;
            case '-' -> num2 - num1;
            case '*' -> num1 * num2;
            case '/' -> num2 / num1;
            default -> -1;
        };
    }

    public boolean isFull(){
        return top == capacity - 1;
    }
    public boolean isEmpty(){
        return top == - 1;
    }
}

总结

关于栈的应用远不止于此,大家也不必全部了解,只要能运用到这种程度,在刷点面试题,应付面试足矣!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

栈的应用-综合计数器的实现 的相关文章

  • Java中ArrayList的交集和并集

    有什么方法可以做到这一点吗 我正在寻找 但没有找到 另一个问题 我需要这些方法 以便我可以过滤文件 有些是AND过滤器 有些是OR过滤器 就像集合论中的那样 所以我需要根据所有文件和保存这些文件的联合 相交 ArrayList 进行过滤 我
  • Gradle 构建错误:无法从 https://repo1.maven.org/maven2/io/fabric/tools/gradle/maven-metadata.xml 加载 Maven 元数据

    我在 Android studio 中遇到 gradle 构建错误 如下所示 Error A problem occurred configuring project MyApp Could not resolve all dependen
  • 如何让 BlazeDS 忽略属性?

    我有一个 java 类 它有一个带有 getter 和 setter 的字段 以及第二对 getter 和 setter 它们以另一种方式访问 该字段 public class NullAbleId private static final
  • .properties 中的通配符

    是否存在任何方法 我可以将通配符添加到属性文件中 并且具有所有含义 例如a b c d lalalala 或为所有以结尾的内容设置一个正则表达式a b c anything 普通的 Java 属性文件无法处理这个问题 不 请记住 它实际上是
  • Spring AspectJ 在双代理接口时失败:无法生成类的 CGLIB 子类

    我正在使用Spring的
  • 谷歌应用程序引擎会话

    什么是java应用程序引擎 默认会话超时 如果我们将会话超时设置为非常非常长的时间 会不会产生不良影响 因为谷歌应用程序引擎会话默认情况下仅存储在数据存储中 就像facebook一样 每次访问该页面时 会话仍然永远存在 默认会话超时设置为
  • Java 集合的并集或交集

    建立并集或交集的最简单方法是什么Set在 Java 中 我见过这个简单问题的一些奇怪的解决方案 例如手动迭代这两个集合 最简单的单行解决方案是这样的 set1 addAll set2 Union set1 retainAll set2 In
  • 检测并缩短字符串中的所有网址

    假设我有一条字符串消息 您应该将 file zip 上传到http google com extremelylonglink zip http google com extremelylonglink zip not https stack
  • 帮助将图像从 Servlet 获取到 JSP 页面 [重复]

    这个问题在这里已经有答案了 我目前必须生成一个显示字符串文本的图像 我需要在 Servlet 上制作此图像 然后以某种方式将图像传递到 JSP 页面 以便它可以显示它 我试图避免保存图像 而是以某种方式将图像流式传输到 JSP 自从我开始寻
  • 像 Java 这样的静态类型语言中动态方法解析背后的原因是什么

    我对 Java 中引用变量的动态 静态类型和动态方法解析的概念有点困惑 考虑 public class Types Override public boolean equals Object obj System out println i
  • 如何在用户输入数据后重新运行java代码

    嘿 我有一个基本的java 应用程序 显示人们是成年人还是青少年等 我从java开始 在用户输入年龄和字符串后我找不到如何制作它它们被归类为 我希望它重新运行整个过程 以便其他人可以尝试 的节目 我一直在考虑做一个循环 但这对我来说没有用
  • 当 OnFocusChangeListener 应用于包装的 EditText 时,TextInputLayout 没有动画

    不能比标题说得更清楚了 我有一个由文本输入布局包裹的 EditText 我试图在 EditText 失去焦点时触发一个事件 但是 一旦应用了事件侦听器 TextInputLayout 就不再对文本进行动画处理 它只是位于 editText
  • 获取文件的总大小(以字节为单位)[重复]

    这个问题在这里已经有答案了 可能的重复 java 高效获取文件大小 https stackoverflow com questions 116574 java get file size efficiently 我有一个名为 filenam
  • java.io.Serialized 在 C/C++ 中的等价物是什么?

    C C 的等价物是什么java io Serialized https docs oracle com javase 7 docs api java io Serializable html 有对序列化库的引用 用 C 序列化数据结构 ht
  • 如何使用 jUnit 将测试用例添加到套件中?

    我有 2 个测试类 都扩展了TestCase 每个类都包含一堆针对我的程序运行的单独测试 如何将这两个类 以及它们拥有的所有测试 作为同一套件的一部分执行 我正在使用 jUnit 4 8 在 jUnit4 中你有这样的东西 RunWith
  • 专门针对 JSP 的测试驱动开发

    在理解 TDD 到底是什么之前 我就已经开始编写测试驱动的代码了 在没有实现的情况下调用函数和类可以帮助我以更快 更有效的方式理解和构建我的应用程序 所以我非常习惯编写代码 gt 编译它 gt 看到它失败 gt 通过构建其实现来修复它的过程
  • 干净构建 Java 命令行

    我正在使用命令行编译使用 eclipse 编写的项目 如下所示 javac file java 然后运行 java file args here 我将如何运行干净的构建或编译 每当我重新编译时 除非删除所有内容 否则更改不会受到影响 cla
  • 使用反射覆盖最终静态字段是否有限制?

    在我的一些单元测试中 我在最终静态字段上的反射中遇到了奇怪的行为 下面是说明我的问题的示例 我有一个基本的 Singleton 类 其中包含一个 Integer public class BasicHolder private static
  • 使用 svn 1.8.x、subclise 1.10 的 m2e-subclipse 连接器在哪里?

    我读到 m2e 的生产商已经停止生产 svn 1 7 以外的任何版本的 m2e 连接器 Tigris 显然已经填补了维护 m2e subclipse 连接器的空缺 Q1 我的问题是 使用 svn 1 8 x 的 eclipse 更新 url
  • 双枢轴快速排序和快速排序有什么区别?

    我以前从未见过双枢轴快速排序 是快速排序的升级版吗 双枢轴快速排序和快速排序有什么区别 我在 Java 文档中找到了这个 排序算法是双枢轴快速排序 作者 弗拉基米尔 雅罗斯拉夫斯基 乔恩 本特利和约书亚 布洛赫 这个算法 在许多数据集上提供

随机推荐

  • 使用jxl解析Excel出现的问题

    jxl read biff BiffException Unable to recognize OLE stream at jxl read biff CompoundFile CompoundFile java 116 at jxl re
  • 【Unity】如何将3D模型呈现在2D平面上

    步骤 一 将2D平面所在Canvas的Render Mode改为Screen Space Camera 改成World Space也行 二 将Main Camera拖动到Render Camera处 三 调整3D模型的大小 2D平面和Mai
  • 基于Numpy构建全连接前馈神经网络进行手写数字识别

    文章目录 一 问题描述 二 设计简要描述 三 程序清单 四 结果分析 五 调试报告 六 实验小结 一 问题描述 不使用任何机器学习框架 仅仅通过Numpy库构建一个最简单的全连接前馈神经网络 并用该网络识别mnist提供的手写数字体 二 设
  • 2023年Java面试题_Redis

    Index Redis 基础 1 基本数据结构 1 1 String 字符串 1 1 1 底层结构 1 1 2 相关指令 1 2 List 列表 1 2 1 底层结构 1 2 2 相关指令 1 3 Hash 哈希 k v 1 3 1 底层结
  • 记一次流量攻击的处理方式

    我本人只是做程序开发的 只会一些基础的linux命令和处理 所以在网上找到了不少方案并且尝试 最终限制了本次的流量攻击 现总结起来 供各位参考 1 首先 我们需要统计一下ip连接数 找到请求过多的ip 将其进行封禁 查看代码如下 netst
  • 人工神经网络算法的学习率有什么作用

    神经网络的结构 例如2输入3隐节点1输出 建好后 一般就要求神经网络里的权值和阈值 现在一般求解权值和阈值 都是采用梯度下降之类的搜索算法 梯度下降法 牛顿法 列文伯格 马跨特法 狗腿法等等 这些算法会先初始化一个解 在这个解的基础上 确定
  • [JAVAee]SpringBoot日志文件

    目录 日志的作用 SpringBoot中的日志 框架说明 日志对象的获取 日志的分类 日志的级别设置 日志的打印 日志的持久化 日志的作用 日志可以帮助我们发现程序的问题并进行定位 日志还可以记录用户的登录信息 分析用户的意图 日志能记录程
  • Vue详情页面el-row el-col做出word样式效果和打印(element-ui)

    场景 业务给了个word文档 然后说要前端可以看到样式如文档 并且可以打印出来 记录一下 element ui word表格样式详情页面 vue页面打印 更细的内容可以查看下面两篇文章原文 样式参考文章 elementUI自定义查看详情组件
  • ModuleNotFoundError: No module named ‘tensorflow‘错误

    环境 win10 64位 情境 eclipse运行python文件 错误 ModuleNotFoundError No module named tensorflow 分析 没有安装tensorflow包 解决方法 pip install
  • QT QProcess执行终端命令并实时输出回显

    https blog csdn net weixin 43690347 article details 84146821 utm medium distribute pc aggpage search result none task bl
  • 【ISP】低亮度图片增强方法(1)

    本文介绍改进INDANE算法的低照度图像增强改进算法 AINDANE算法 Adaptive and integrated neighborhood dependent approach for nonlinear enhancement o
  • 如何用RDP来连接计算机上的WSL2(Ubuntu)图形界面(要求安装Gnome桌面)

    您可以使用 Remote Desktop Protocol RDP 连接 Windows Subsystem for Linux WSL 中的 Ubuntu 系统的图形界面 需要安装 Gnome 桌面 在 Ubuntu 系统中安装并启动 V
  • TCP/IP四层模型简述

    1 TCP IP协议是由七层模型简化成四层而来 七层有底向上分别是 物理层 数据链路层 网络层 传输层 会话层 表示层 应用层 简化后的四层分别是 主机到网络层 比特 网络层 数据帧 传输层 数据包 应用层 数据段 每一层对于上一层来讲是透
  • axure读取服务器文件,axure 云服务器

    axure 云服务器 内容精选 换一换 监控是保持弹性云服务器可靠性 可用性和性能的重要部分 通过监控 用户可以观察弹性云服务器资源 为使用户更好地掌握自己的弹性云服务器运行状态 公有云平台提供了云监控 您可以使用该服务监控您的弹性云服务器
  • (pytorch进阶之路)Masked AutoEncoder论文及实现

    文章目录 1 导读 2 论文地址 3 代码实现思路 3 1 预处理阶段 3 2 Encoder 3 3 Decoder 3 4 fine tuning 3 5 linear probing 3 6 evaluation 4 代码地址 5 如
  • 闪烁回路的例子 三菱PLC ST语言 梯形图

    闪烁回路的例子 使可编程控制器运行 通过初始脉冲 M8002 驱动状态S3 在状态S3中输出Y000 1秒钟以后转移到状态S20 在状态S20中输出Y001 1 5秒钟以后返回状态S3 ST SET M8002 S3 STL TRUE S3
  • Docker 中国官方镜像加速

    通过 Docker 官方镜像加速 中国区用户能够快速访问最流行的 Docker 镜像 该镜像托管于中国大陆 本地用户现在将会享受到更快的下载速度和更强的稳定性 从而能够更敏捷地开发和交付 Docker 化应用 Docker 中国官方镜像加速
  • vue3+ts+element-plus 列表查询条件/筛选条件组件二次封装(条件查询组件新增继承第三方组件事件)

    2023 06 08 条件查询组件新增继承第三方组件事件 效果如下 一 需求 对于后台管理系统项目必不可少的就是 增删改查 而 查 就会根据表格的列数来显示多少个查询 筛选条件 为了方便因此封装了查询条件 筛选条件 组件 二 组件功能 1
  • 低级处理函数ProcessFunction

    原文链接 https zhuanlan zhihu com p 130708277 1 ProcessFunction定义 ProcessFunction 函数是低阶流处理算子 可以访问流应用程序所有 非循环 基本构建块 事件 数据流元素
  • 栈的应用-综合计数器的实现

    目录 前言 一 思路分析 二 代码实现 总结 前言 在实现综合计数器之前 大家应该先了解一下什么是前中后缀表达式 前缀 中缀和后缀表达式是表示数学表达式的三种不同方式 前缀表达式 也称为波兰式或前缀记法 操作符位于操作数之前 例如 2 3