【数据结构与算法 6】栈实现综合计算器

C++:将表达式构建为二叉树实现一个简单计算器 用c++实现一个计算器,支持整数、小数的”+ - * / “四则运算,允许含有括号。这里默认输入均为正常表达式,结果精确到小数点后三位。具体解释详见代码注释。 阅读详情

一、栈

栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

二、栈的应用场景

1、子程序的调用

在调往子程序前,会先将下个指令的地址存放到堆栈中,直到子程序执行完后再将地址抛出,以回到原来的程序。

2、处理递归调用

和子程序的调用类似,除了村下个指令的地址外,还要存放参数,区域变量等数据。

3、表达式的转换

中缀表达式转后缀表达式

4、二叉树的遍历

5、图形的深度优先搜索法

三、栈实现综合计算器(中缀表达式)

1、思路分析

  • 通过一个index值(索引),来遍历我们的表达式
  • 如果发现是一个数字直接入数栈
  • 如果发现当前的符号栈是空,就直接入栈
  • 如果发现符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或等于栈中的操作符,就需要从数栈中pop出一个符号,进行运算,将得到结果,入数栈,然后将当前的操作符入符号栈,如果当前的操作符的优先级大于栈中的操作符,就直接入符号栈。
  • 当表达式扫描完毕,就顺序的从数栈和符号栈中pop出相应的数和符号,并进行运算。
  • 最后在数栈中只有一个数字,就是表达式的结果。

2、代码实例

(1)ArrayStack工具类

package dataStructure.stack;

public class ArrayStack {
    private int maxSize; // 栈的大小
    private int[] stack; // 数组,数组模拟栈,数据就放在该数组
    private int top = -1;// top表示栈顶,初始化为-1

    //构造器
    public ArrayStack(int maxSize) {
        this.maxSize = maxSize;
        stack = new int[this.maxSize];
    }

    //增加一个方法,可以返回当前栈顶的值, 但是不是真正的pop
    public int peek() {
        return stack[top];
    }

    //栈满
    public boolean isFull() {
        return top == maxSize - 1;
    }
    //栈空
    public boolean isEmpty() {
        return top == -1;
    }
    //入栈-push
    public void push(int value) {
        //先判断栈是否满
        if(isFull()) {
            System.out.println("栈满");
            return;
        }
        top++;
        stack[top] = value;
    }
    //出栈-pop, 将栈顶的数据返回
    public int pop() {
        //先判断栈是否空
        if(isEmpty()) {
            //抛出异常
            throw new RuntimeException("栈空,没有数据~");
        }
        int value = stack[top];
        top--;
        return value;
    }
    //显示栈的情况[遍历栈], 遍历时,需要从栈顶开始显示数据
    public void list() {
        if(isEmpty()) {
            System.out.println("栈空,没有数据~~");
            return;
        }
        //需要从栈顶开始显示数据
        for(int i = top; i >= 0 ; i--) {
            System.out.printf("stack[%d]=%d\n", i, stack[i]);
        }
    }
    //返回运算符的优先级,优先级是程序员来确定, 优先级使用数字表示
    //数字越大,则优先级就越高.
    public int priority(int oper) {
        if(oper == '*' || oper == '/'){
            return 1;
        } else if (oper == '+' || oper == '-') {
            return 0;
        } else {
            return -1; // 假定目前的表达式只有 +, - , * , /
        }
    }
    //判断是不是一个运算符
    public boolean isOper(char val) {
        return val == '+' || val == '-' || val == '*' || val == '/';
    }
    //计算方法
    public int cal(int num1, int num2, int oper) {
        int res = 0; // res 用于存放计算的结果
        switch (oper) {
            case '+':
                res = num1 + num2;
                break;
            case '-':
                res = num2 - num1;// 注意顺序
                break;
            case '*':
                res = num1 * num2;
                break;
            case '/':
                res = num2 / num1;
                break;
            default:
                break;
        }
        return res;
    }
}

(2)测试类

package dataStructure.stack;

public class Calculator {
    public static void main(String[] args) {
        //根据前面老师思路,完成表达式的运算
        String expression = "100/5+2*3-1"; // 25
        //创建两个栈,数栈,一个符号栈
        ArrayStack numStack = new ArrayStack(10);
        ArrayStack operStack = new ArrayStack(10);
        //定义需要的相关变量
        int index = 0;//用于扫描
        int num1 = 0;
        int num2 = 0;
        int oper = 0;
        int res = 0;
        char ch = ' '; //将每次扫描得到char保存到ch
        String keepNum = ""; //用于拼接 多位数
        //开始while循环的扫描expression
        while (true) {
            //依次得到expression 的每一个字符
            ch = expression.substring(index, index + 1).charAt(0);
            //判断ch是什么,然后做相应的处理
            if (operStack.isOper(ch)) {//如果是运算符
                //判断当前的符号栈是否为空
                if (!operStack.isEmpty()) {
                    //如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或者等于栈中的操作符,就需要从数栈中pop出两个数,
                    //在从符号栈中pop出一个符号,进行运算,将得到结果,入数栈,然后将当前的操作符入符号栈
                    if (operStack.priority(ch) <= operStack.priority(operStack.peek())) {
                        num1 = numStack.pop();
                        num2 = numStack.pop();
                        oper = operStack.pop();
                        res = numStack.cal(num1, num2, oper);
                        //把运算的结果如数栈
                        numStack.push(res);
                        //然后将当前的操作符入符号栈
                        operStack.push(ch);
                    } else {
                        //如果当前的操作符的优先级大于栈中的操作符, 就直接入符号栈.
                        operStack.push(ch);
                    }
                } else {
                    //如果为空直接入符号栈..
                    operStack.push(ch); // 1 + 3
                }
            } else { //如果是数,则直接入数栈

                //numStack.push(ch - 48); //? "1+3" '1' => 1
                //分析思路
                //1. 当处理多位数时,不能发现是一个数就立即入栈,因为他可能是多位数
                //2. 在处理数,需要向expression的表达式的index 后再看一位,如果是数就进行扫描,如果是符号才入栈
                //3. 因此我们需要定义一个变量 字符串,用于拼接

                //处理多位数
                keepNum += ch;

                //如果ch已经是expression的最后一位,就直接入栈
                if (index == expression.length() - 1) {
                    numStack.push(Integer.parseInt(keepNum));
                } else {
                    //判断下一个字符是不是数字,如果是数字,就继续扫描,如果是运算符,则入栈
                    //注意是看后一位,不是index++
                    if (operStack.isOper(expression.substring(index + 1, index + 2).charAt(0))) {
                        //如果后一位是运算符,则入栈 keepNum = "1" 或者 "123"
                        numStack.push(Integer.parseInt(keepNum));
                        //重要的!!!!!!, keepNum清空
                        keepNum = "";
                    }
                }
            }
            //让index + 1, 并判断是否扫描到expression最后.
            index++;
            if (index >= expression.length()) {
                break;
            }
        }

        //当表达式扫描完毕,就顺序的从 数栈和符号栈中pop出相应的数和符号,并运行.
        while (true) {
            //如果符号栈为空,则计算到最后的结果, 数栈中只有一个数字【结果】
            if (operStack.isEmpty()) {
                break;
            }
            num1 = numStack.pop();
            num2 = numStack.pop();
            oper = operStack.pop();
            res = numStack.cal(num1, num2, oper);
            numStack.push(res);//入栈
        }
        //将数栈的最后数,pop出,就是结果
        int res2 = numStack.pop();
        System.out.printf("表达式 %s = %d", expression, res2);
    }
}

3、控制台输出

利用栈实现计算器(calculator)一:基本思路及实现 github:https://github.com/AnkangH/优快云/blob/master/%E5%88%A9%E7%94%A8%E6%A0%88%E5%AE%9E%E7%8E%B0%E8%AE%A1%E7%AE%97%E5%99%A8/01.%E5%9F%BA%E6%9C%AC%E6%80%9D%E8%B7%AF%E5%8F%8A%E5%88%9D%E6%AD%A5%E5%8A%9F%... 阅读详情

相关推荐

二叉树思想实现的计算器

实现一个简单的计算器。通过键盘输入一个包含圆括号、加减乘除等符号组成的算术表达式字符串,输出该算术表达式的值。要求: (1)系统至少能实现加、减、乘、除等运算; (2)利用二叉树算法思想求解表达式的值,先构造由表达式构成的二叉树,然后再利用通过对二叉树进行后序遍历求解算术表达式的值。 #include <iostream> #include <string> #include <sstream> #include <stack> #include <cm

weixin_46142447的博客 2605

利用栈实现简易计算器(含代码)

思路: 计算器的简单实现 实现计算机的加、减、乘、除操作 eg:3+2*4-20/4 = 3+8-5 = 6 1.定义index对表达式进行扫描; 创建两个栈,一个栈存放数字,称为数栈(numStack);一个栈存放符号,称为符号栈(symbolStack); 2.当遇到数字时,入数栈;(注意字符位数,数字有可能是多位数) 2.1若是字符串最后一个的时候,直接入数栈 2.2若不是最后一个字符,需要再往后判断一位,若后一位不是符号,继续遍历,并将该字符拼接;若是则...

Angety 的博客 4303

【STM32+HAL】LCD实现栈计算器

芯片:STM32F407ZGT6 实现功能:加减乘除、指数对数、三角函数、括号及小数

手把手带你利用栈来实现一个简易版本的计算器

一文掌握栈的四大经典应用场景:括号配对,表达式求值,浏览器前进后退,函数调用;手把手实现一个简易版本的计算器。

zwx900102的博客 2544

二阶高通滤波器硬件设计:5种RC到有源方案对比与选型

在传感器前端和音频信号调理中,二阶高通滤波器是抑制直流偏移与低频干扰的关键模块。其设计核心围绕截止频率、品质因数Q、增益与噪声四个指标展开,其中Q值决定滤波器在转折频率附近的响应形状,如Butterworth最大平坦响应需Q=0.707。从纯无源RC电路到引入运放的有源拓扑,演变逻辑在于解决负载效应、提供增益并借助反馈提升Q值。实际工程中,RC级联、VCVS(Sallen-Key)、状态变量及回转器模拟电感等方案各有适用场景:RC电路简单但Q值受限,Sallen-Key单运放即可实现高Q,状态变量适合Q值独

weixin_32770423的博客 97

2026年7月19日 从可插拔到共封装:技术路线研究报告

AI 算力的爆发正在重写数据中心光互连的技术路线。本报告对当前并存的四代光互连架构——

weixin_51184047的博客 583

韩顺平 数据结构与算法 (6)栈实现综合计算器

—————————>栈实现综合计算器<———————— 思路分析 1. 通过一个index值(索引),来遍历表达式 2. 如果我们**发现是一个数字**,就直接**入数栈** 3. 如果我们**发现是一个符号**,就分两种情况 1. 符号栈**为空**,就直接入栈 2. 符号栈**不空**,就进行比较— 1. 如果**当前的操作符的优先级<=栈中的操作符**:就需要从数栈中pop出两个数,再从符号栈中pop出一个符号,进行运算,将结果入数栈,

weixin_52184392的博客 433

Dzzoffice结合OnlyOffice 报错排查流程总结

首先访问 OnlyOffice 首页,如下图:出现上图仍旧不能说明你的 OnlyOffice 服务已经成功安装,我们需要启动 OnlyOffice 服务测试用例来检测,可以看到上图出现了两条命令,第一条命令是用来启动测试用例服务的,我们只需要在后台执行该命令即可,Windows环境是以管理员身份运行Windows PowerShell输入即可运行了。

小胡的博客 4595

Java尚硅谷数据结构与算法学习记录(6)续-栈实现综合计算器

栈实现综合计算器(中缀表达式) 思路分析: 需要两个栈:数栈和符号栈 定义一个index索引来遍历表达式 遍历到一个数字,则入数栈 遍历到一个符号,若符号栈为空则入符号栈; 若符号栈不为空:如果当前遍历到的符号优先级小于或等于符号栈中符号的优先级,则从数栈中pop出两个数,从符号栈中pop出一个符号,进行运算,然后将运算结果入数栈,将当前遍历到的符号入符号栈;如果当前遍历到的符号优先级大于符号栈中符号优先级,则将该符号直接入符号栈。 表达式遍历完毕后,则按顺序从数栈和符号栈中pop出值进行运算 最后数栈

qq_38715538的博客 306

从零到一:基于GeneMark-ES/ET的新基因组注释实战指南

本文提供了一份基于GeneMark-ES/ET的新基因组注释实战指南。详细介绍了从环境搭建、数据准备到核心运行的全流程,重点解析了ES(从头预测)与ET(结合RNA-Seq证据)两种模式的选择与操作,并分享了Perl模块依赖、并行处理等常见问题的解决方案,帮助生物信息学研究者高效完成基因预测工作。

weixin_29266647的博客 209

RandLA-Net 调通代码1:Windows 11 + Tensorflow 2.4 + S3DIS数据集【踩坑+填坑】

TF不上进啊,学学pytorch

累了就要打游戏 2480

使用数组手写原声栈,实现综合计算器

使用数组模拟栈,实现综合计算器

qq_53933886的博客 176

2026年最值得学习的十大 SAP 开发技术

在这辞旧迎新之际,我想和大家聊聊我心中的2026年我仍然愿意持续投入时间去学习的一些 SAP 开发技术。因为笔者水平和视野局限,加上这份清单有笔者主观兴趣爱好在内,可能大家对清单上罗列的技术有不同意见,欢迎大家在评论区发表自己的见解。下面是笔者列出的十个技术方向,排名不分先后。因为精力有限,2026年我很可能只会选择其中一两个自己最感兴趣的方向去深耕。每项技术后面都提供了链接,方便大家看完就开始学习。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1519

数据结构3(栈与栈综合计算器)

摘要:本文详细介绍了栈的基本概念、特点及其应用场景。栈是一种先入后出的线性表,支持在栈顶进行插入(push)和删除(pop)操作。文章阐述了数组和链表两种实现栈的方式,并提供了Java代码示例。重点讲解了栈在表达式计算中的运用,包括中缀表达式转后缀表达式的方法,以及逆波兰表达式(后缀表达式)和波兰表达式(前缀表达式)的计算原理和实现步骤。

rengengliuli的博客 1635

信号与电源完整性5:轨道塌陷噪声/电源轨道噪声分析及降低解决方案

经过上一节关于串扰的分析,我们已经清楚,噪声问题不仅仅来源于信号网络;电源和地网络所产生的噪声,被反馈到其所在的元器件和信号网络时,其破坏力也是巨大的;本节所讨论的轨道塌陷噪声就是一个典型的实例。在经过电源的地网络的电流发生改变时,在电源和地之间的阻抗上将产生一个压降;由于该压降的产生,用电元件的电压将直接被拉低,甚至可能对电路产生功能性的错误。接下来硬小二将详细的分析电源轨道噪声和降低其的解决方法。...

fydar的博客 2241

【我的Android进阶之旅】解决android应用使用android:persistent属性带来的系统Launcher应用必须重启设备才生效的问题,大幅度提升开发效率

一、问题描述 我们在开发系统级别应用,比如Launcher桌面的时候,会发现有个问题:每次Launcher修改完代码,重新编译之后,安装到android设备上之后,必须重启才会生效。否则就是使用了之前的Launcher版本的内容。而每次重启设备得一分钟左右,太慢了,太影响效率了! 1.1 痛点 每次更新完代码,重新安装之后,必须重启设备才会生效。效率太TM低了! 二、分析问题 经过一轮代码排查,最终发现是因为src\main\AndroidManifest.xml文件中,定义application使用了an

字节卷动 1711

数据结构【栈】栈的基本概述以及综合计算器的实现

1 栈的概述以及基本代码实现 栈(Stack)是一种先入后出的有序列表,先进入的元素总是存在于栈底。删除和加入新元素都是在栈顶进行操作的 简单的代码实现如下,主要就是一个固定大小的数组stack(这里假设是专门放整数的数组),一个栈顶指针top class ArrayStack{ private int maxSize; private int[] stack; private int t...

ligen1112的博客 427

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

数据结构与算法--Python栈 栈实现综合计算器和逆波兰计算器 前缀表达式 中缀表达式 后缀表达式 逆波兰表达式

Python栈 栈实现综合计算器和逆波兰计算器

storyfull 1242

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

数据结构与算法——Java实现栈、逆波兰计算器(整数加减乘除)

我们平时使用的计算器,其底层就是利用了栈这个概念对这个算式进行理解栈的英文为(stack)栈是一个先入后出(FILO-First In Last Out)的有序列表(stack)是限制表素的插入和除只能在性的同一端进行的一种性表。允许插入和删除的端,为变化的一端,称为栈顶(Top),另一端为固定的一端,称为栈底(Bottom)根据栈的定义可知,最先放入栈中元素在栈底,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素最后删除图解方式说明。

weixin_51351637的博客 1959

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器

文章目录前言一、栈1.1 栈的介绍1.2 栈的应用实例【重点】1.3 栈的应用场景二、数据模拟栈三、单链表模拟栈四、栈实现综合计算器 前言 一、栈 1.1 栈的介绍 栈的英文为(stack) 栈是一个 先入后出 (FILO-First In Last Out)的有序列表。 栈(stack)是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表。允许插入和删除的一端,为变化的一端,...

冯安晨 533

数据结构(C语言)用链栈来实现计算器

数据结构顺序栈实现简单计算器的操作 未改进,只能计算输出结果是个位数的数值计算 #include<stdio.h> #include<string.h> #include<malloc.h> #include<stdlib.h> #include<iostream> #define OK 1 #define ERROR 0 #define...

qq_44024359的博客 1953

(数据结构与算法)使用栈来实现综合计算器

1.栈实现综合计算器(中缀表达式) 1.1流程图 1.2 代码实现 public class Calculator { public static void main(String[] args) { String expression = "700*2*2-5+1-5+3-4"; //创建数栈和运算符栈 ArrayStackCal numStack = new ArrayStackCal(10); ArrayStackCal ope

我真的很不错的博客 783

Java数据结构(7)----栈实现综合计算器(带多重括号)

栈实现综合计算器(带多重括号) 前言 今天学习了栈如何实现综合计算器,现在我们来总结一下,再自己画画图深入理解一下,再实现一下没有实现的功能,如何运算带多重括号的运算表达式 比如这个 (((1623(25-5))+1-5)*3-4)/2 表达这个。 思路: 通过一一个index值(索引),来遍历我们的运算表达式 如果我们发现是一个数字,就直接入数栈, 发现是符号就进符号栈 如果发现当前的符号栈为...

qq_44752800的博客 1862

个人数据结构与算法学习总结-栈、实现综合计算器、递归

栈 本总结主要是以“尚硅谷Java算法教程”的学习教程为主,加上一些个人的理解 目录栈栈介绍介绍出栈和入栈的图示栈的应用场景实现栈利用栈实现综合计算器前缀、中缀、后缀表达式设计逆波兰计算器 栈介绍 介绍 栈的英文为(stack),是一个先入后出(FILO-First In Last Out)的有序列表。栈(stack)是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表。允许插入和删除的一端,为变化的一端,称为栈顶(Top),另一端为固定的一端,称为栈底(Bottom)。 根据栈的定义可知

qq_39084191的博客 510
上一篇: 【进击全栈 2】项目开发中遇到的问题汇总
下一篇: 【数据结构与算法 7】中缀表达式转为后缀表达式,实现逆波兰计算器
哪 吒
哪 吒 2022年度博客之星TOP 1 2022年度博客之星TOP 1 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 59万+粉丝 2933原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值