栈的应用-综合计数器的实现-程序员宅基地

技术标签: java  数据结构与算法  数据结构  

目录

前言

一、思路分析

二、代码实现

总结

前言

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

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

  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;
    }
}

总结

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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_73869209/article/details/132791952

智能推荐

鸿蒙系统电池耗电,都说iPhone是伪后台,不用关闭程序,一点不耗电,为什么电池里头看使用情况后台耗电这么多?...-程序员宅基地

文章浏览阅读4.4k次。如果说伪后台=单任务,那ios已经死很久了。iOS是支持后台管理的,但是并不是所有的应用程序,也就支持音乐,下载APP,消息推送以及通知会后台运行。例如当你点击home键切换到桌面的时候,你之前运行的程序大多数都会断掉,如果再切换回来,就会出现重新加载的画面,当然,如果你切换回来的时间并不长的话是不会重新加载的。如果是视频或者游戏,当你切换出去的时候它们会自动暂停在那里,不会进行缓冲等后台运行。这..._鸿蒙是伪后台吗

十折交叉验证python_Python实现K折交叉验证法的方法步骤-程序员宅基地

文章浏览阅读1.2k次。##一个简单的2折交叉验证from sklearn.model_selection import KFoldimport numpy as npX=np.array([[1,2],[3,4],[1,3],[3,5]])Y=np.array([1,2,3,4])KF=KFold(n_splits=2) #建立4折交叉验证方法 查一下KFold函数的参数for train_index,test_ind..._python十折交叉验证结果解读

默认ip_基于EtherNet/IP实现欧姆龙NX系列PLC通信-程序员宅基地

文章浏览阅读2.6k次。1、引言工业以太网协议 (Ethernet/IP) 是由ODVA所开发并得到了罗克韦尔自动化的强大支持。它使用已用于ControlNet和DeviceNet的控制和信息协议 (CIP) 为应用层协议。 CIP提供了一系列标准的服务,提供“隐式”和“显示”方式对网络设备中的数据进行访问和控制。CIP数据包必须在通过以太网发送前经过封装,并根据请求服务类型而赋予一个报文头。这个报文头指示了..._欧姆龙plc默认ip

请输入星期几的第一个字母来判断一下是星期几,如果第一个字母一样,则继续判断第二个字母_起诉星期几的第一个字用来判断星期几如果第一层膜一样则继续判断第二个字伊一-程序员宅基地

文章浏览阅读2.8k次。char a = '0'; printf("请输入当前星期数的首字母:\n"); scanf("%c", &a); getchar(); if (a == 'm') { printf("星期一\n"); } else if (a =='w') { printf("星期三\n"); } else if_起诉星期几的第一个字用来判断星期几如果第一层膜一样则继续判断第二个字伊一

maven-程序员宅基地

文章浏览阅读580次。1.下载,配置bin目录到path中,mvn -v 测试是否配置成功2.F:\apache-maven-3.5.0-bin\apache-maven-3.5.0\conf\setting.xml里面配置本地仓库的地址 F:\mavenresp3.maven项目的约定的目录结构src/main/java 存放项目的java文件src/main/resources

Unix传奇(下篇)-程序员宅基地

文章浏览阅读78次。Unix是目前还在存活的操作系统的元老了,走过了40年的历程(参看《Unix 40年:Unix年鉴》、《Unix 40年:昨天,今天和明天》)。由它引发的思想变革,对当今计算机文化造成的深远影响。这是一段所有从事计算机行业人员尤其是软件开发人员需要了解的历史。Unix的传奇历史是整个计算机世界文化最具代表性的,它对整个计算机世界文化的影响也是最巨大,最深远的。他给人带来的不单单的对过去的回..._unix传奇

随便推点

android----下载android-4.2源码_5g天天奭5g运动免费入口-程序员宅基地

文章浏览阅读5k次。官网指南:http://source.android.com/source/building-running.html1、安装git和curl 进入Linux ,打开终端,在终端窗口敲下面的命令: sudo apt-get install git-core curl 2、安装repo脚本 首先安装repo。在当前用户:~目录下新建一个bin目录。然后,向PATH_5g天天奭5g运动免费入口

CISCN PWN签到题 task_note_service_easypwn addnote deletenote editnote-程序员宅基地

文章浏览阅读1.6k次。序言 比赛中这道差那么一点点就做出来了程序运行1.menu---------menu---------1. add note2. show note3. edit note4. del note5. exityour choice&gt;&gt;2. add1. add note2. show note3. edit note4. del..._easypwn addnote deletenote editnote

大语言模型?生成式AI?分不清楚的话可以看aws这个例子_生成式ai 大语言模型-程序员宅基地

文章浏览阅读468次。Amazon Bedrock汇聚了众多领先的大语言模型,用户只需通过单一API就能利用来自AI21 Labs、Anthropic、Cohere、Meta Llama2、Stability AI等公司的先进大语言模型来构建自己的应用。除此之外,大语言模型还可应用于舆情分析、自动代码生成、自动问答系统等多个领域,随着技术的不断进步和应用领域的不断拓展,大语言模型具有巨大的潜力和广泛的应用前景。文本生成:大语言模型可以根据给定的上下文或提示,生成连贯、富有创意的文本内容,如文章、故事、诗歌等。_生成式ai 大语言模型

PAT——甲级1046(最短路径)-程序员宅基地

文章浏览阅读421次。英文题,看终于看懂了,要逐字一个个地翻译一开始以为是要用到图的知识后来发现 就先简单的相减求最小值#include&lt;cstdio&gt;#include&lt;algorithm&gt;using namespace std;#define maxn 100005int main(){ int m,n,i,j; int sum=0; int a..._甲级1046

Python常见实战问题解析与解决方案_python问题-程序员宅基地

文章浏览阅读1k次,点赞19次,收藏19次。在本文中,深入研究了Python中的常见实战问题及其解决方案,为大家提供了全面的解决方案和实例代码。首先,探讨了内存泄漏问题,并演示了如何通过使用弱引用等手段来有效地解决这类问题,确保程序的内存使用得到良好的管理。其次,重点关注了性能优化,介绍了数据结构的优化、生成器的应用,以及多线程的实际使用,旨在更好地理解和运用这些技术以提高程序效率。异常处理和调试作为开发中不可避免的一环,也在文章中得到充分关注。演示了如何使用try和except处理异常,以及如何利用Python内置的调试工具pdb。_python问题

基于C++实现视频聊天软件(一)_视频通话cpp-程序员宅基地

文章浏览阅读1.4w次,点赞14次,收藏104次。初来乍到,接触到音视频领域,在这期间参考开源代码和项目代码,用C++做了一个类似QQ的视频聊天Demo,这里将其中开源的视频通讯技术分享给大家。 工具: vs2010,MFC制作界面,网络传输机制(Socket等), VFW视频采集,FFmpeg编解码器,SDL播放_视频通话cpp

推荐文章

热门文章

相关标签