数据结构与算法之中缀表达式的求值

article/2025/7/12 19:33:57
栈的一个实际需求
  • 请输入一个表达式
  • 计算式:[7*22-5+1-53-3]点击计算【如下图】
    栈的应用
栈的介绍
  • 栈的英文为stack(stack)。
  • 栈是一个先入后出(FILO-First In Last Out)的有序列表。
  • 栈(stack)是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表。允许插入和删除一端,为变化的一端,称为栈顶(Top),另一端为固定的一端,称为栈底(Bottom)
  • 根据栈的定义可知,最先放入栈中元素在栈底,最后放入的元素在栈顶。而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素最后删除。
  • 图解说明出栈(pop)和入栈(push)的概念
    栈
  • 栈的应用场景
    • 子程序的调用:在跳往子程序前,会先将下个指令的地址存到堆栈中,直到子程序执行完后将地址取出,以回到原来的程序中。
    • 处理递归调用:和子程序的调用类似,只是除了存储下一个指令的地址外,也将参数、区域变量等数据存入堆栈中。
    • 表示的转换[中缀表达式转后缀表达式]与求值(实际解决)
    • 二叉树的遍历。
    • 图形的深度优先(dept-first)搜索法。
栈的快速入门
  • 用数组模拟栈的使用,由于栈是一种有序列表,当然可以使用数组的结构来存储栈的数据内容。
  • 栈
    实现思路分析,并画出示意图
import java.util.Scanner;/*** 数组模拟栈*/
public class ArrayStackDemo {public static void main(String[] args) {// 创建一个栈ArrayStack arrayStack = new ArrayStack(3);Scanner scanner = new Scanner(System.in);String key;mywhile:while(true) {System.out.println("push:将一个元素压入栈中");System.out.println("pop:从栈中弹出一个元素");System.out.println("show:显示栈中所有元素");System.out.println("peek:查看栈顶元素");System.out.println("exit:退出系统");System.out.print("请选择你要执行的惭怍:");key = scanner.next();switch(key) {case "push":System.out.println("请选择你要压入栈中的元素");int value = scanner.nextInt();arrayStack.push(value);break;case "pop":try{System.out.println("弹出的元素是:" + arrayStack.pop());}catch(Exception e) {System.out.println(e.getMessage());}break;case "peek":try{System.out.println("栈顶的元素是:" + arrayStack.peek());}catch(Exception e) {System.out.println(e.getMessage());}break;case "show":arrayStack.display();break;case "exit":scanner.close();break mywhile;default:break;}}System.out.println("已退出系统,欢迎下次使用");}
}
class ArrayStack {int top;int[] arrStack;int maxSize;public ArrayStack(int maxSize) {this.maxSize = maxSize;arrStack = new int[maxSize];top = -1;}// 将元素压入栈中public void push(int value) {if(isFull()) {System.out.println("栈已满,不能压入");return;}arrStack[++top] = value;}// 从栈中弹出元素public int pop() {if(isEmpty()) {throw new RuntimeException("栈为空");}return arrStack[top--];}// 查看栈顶元素public int peek() {if(isEmpty()) {throw new RuntimeException("栈为空");}return arrStack[top];}// 遍历栈中所有信息public void display() {if(isEmpty()) {System.out.println("栈空,没有数据");return;}for(int i = top;i >= 0;i--) {System.out.printf("stack[%d]=%d\n",i,arrStack[i]);}}/*** 判断栈是否满* @return*/public boolean isFull() {return top == maxSize - 1;}// 判断栈是否为空public boolean isEmpty() {return top == -1;}
}
  • 练习:使用链表来模拟栈
栈实现综合计算器(中缀表达式)
  • 使用栈来实现综合计算器
    栈
  • 思路分析
    中缀表达式
  • 代码实现
public class InffixExpressionValue {public static void main(String[] args) {// 要求值的表达式String expression = "100-2*3*7-5";// 定义两个栈,一个用来存放操作数,一个用来存放操作符ArrayStack2 numStack = new ArrayStack2(10);ArrayStack2 operStack = new ArrayStack2(10);String keepNum = ""; // 用来拼接多位数int num1 = 0;int num2 = 0;int oper = 0;int res = 0;for(int i = 0; i < expression.length(); i++){char ch = expression.substring(i, i + 1).charAt(0);// 如果是运算符if(operStack.isOper((ch))) {// 判断操作符栈中有没有运算符,没有,直接压入栈中if(operStack.isEmpty()) {operStack.push(ch);continue;}// 有的话比较优先级,依次弹出栈中优先级大于等于ch的,并进行计算while(!operStack.isEmpty() && operStack.priority(ch) <= operStack.priority(operStack.peek())) {num1 = numStack.pop();num2 = numStack.pop();oper = operStack.pop();res = numStack.calculate(num1,num2,oper);numStack.push(res);}// 将该运算符入栈operStack.push(ch);}else {// 如果是数字直接入数栈
//                numStack.push(ch - 48);// 分析思路:// 1.当处理多位数时,不能发现是一个数就立即入栈,因为它可能时多位数// 2.在处理数时,需要向expression的表达式的i后再看一位,如果时数进行扫描。如果是符号才入栈keepNum = keepNum +  ch;while((i + 1 < expression.length())) {char ch1 = expression.substring(i + 1, i + 2).charAt(0);if(operStack.isOper(ch1)) {break;}keepNum = keepNum + ch1;i++;}numStack.push(Integer.parseInt(keepNum));keepNum = "";}}// 依次弹出操作符栈和操作数栈中的数字进行运算while(!operStack.isEmpty()) {num1 = numStack.pop();num2 = numStack.pop();oper = operStack.pop();res = operStack.calculate(num1,num2,oper);numStack.push(res);}// 直到操作数栈为空,弹出操作数栈的元素就是最终结果System.out.printf("表达式%s的值是%d",expression,numStack.pop());}}class ArrayStack2 {int top;int[] arrStack;int maxSize;public ArrayStack2(int maxSize) {this.maxSize = maxSize;arrStack = new int[maxSize];top = -1;}// 将元素压入栈中public void push(int value) {if(isFull()) {System.out.println("栈已满,不能压入");return;}arrStack[++top] = value;}// 从栈中弹出元素public int pop() {if(isEmpty()) {throw new RuntimeException("栈为空");}return arrStack[top--];}// 查看栈顶元素public int peek() {if(isEmpty()) {throw new RuntimeException("栈为空");}return arrStack[top];}// 遍历栈中所有信息public void display() {if(isEmpty()) {System.out.println("栈空,没有数据");return;}for(int i = top;i >= 0;i--) {System.out.printf("stack[%d]=%d\n",i,arrStack[i]);}}/*** 判断栈是否满* @return*/public boolean isFull() {return top == maxSize - 1;}// 判断栈是否为空public boolean isEmpty() {return top == -1;}// 计算,注意num2是左边的操作数,num1是右边的操作数public static int calculate(int num1, int num2, int oper) {int result = 0;switch(oper) {case '+':result = num1 + num2;break;case '-':result = num2 - num1;break;case '*':result = num1 * num2;break;case '/':result = num2 / num1;break;}return result;}/*** 判断是传入的是不是操作符* @param ch* @return*/public static boolean isOper(int ch) {return ch == '+' || ch == '-' || ch == '*' || ch == '/';}public static int priority(int ch) {int priority = -1;switch(ch) {case '*': case '/':priority = 2;break;case '+': case '-':priority = 1;break;}return priority;}
}
  • 练习:给表达式加入小括号

http://www.hkcw.cn/article/ogAVpkNtPB.shtml

相关文章

显卡3080和4060哪个强 两款游戏性能对比

对于硬核玩家而言&#xff0c;选择一款合适的显卡至关重要。在市场上&#xff0c;NVIDIA的3080和4060两款显卡备受关注。很多朋友在选择时会疑惑&#xff0c;究竟是3080更强&#xff0c;还是4060更具性价比呢&#xff1f;今天我们就来深入分析这两款显卡&#xff0c;帮助大家做…

Visual Studio 2022 发布独立的 exe 文件

我们在用 Visual Studio 2022 写好一个 exe 程序之后&#xff0c;如果想把这个拿到其他地方运行&#xff0c;需要把 exe 所在的文件夹一起拿过去。 编译出来的 exe 文件需要其他几个文件一同放在同一目录才能运行&#xff0c;原因在于默认情况下&#xff0c;Visual Studio 是把…

若依项目AI 助手代码解析

基于 Vue.js 和 Element UI 的 AI 助手组件 一、组件整体结构 这个 AI 助手组件由三部分组成&#xff1a; 悬浮按钮&#xff1a;点击后展开 / 收起对话窗口对话窗口&#xff1a;显示历史消息和输入框API 调用逻辑&#xff1a;与 AI 服务通信并处理响应 <template><…

Java源码中有哪些细节可以参考?(持续更新)

欢迎来到啾啾的博客&#x1f431;。 记录学习点滴。分享工作思考和实用技巧&#xff0c;偶尔也分享一些杂谈&#x1f4ac;。 有很多很多不足的地方&#xff0c;欢迎评论交流&#xff0c;感谢您的阅读和评论&#x1f604;。 目录 String的比较final的使用transient避免序列化 St…

Linux | Shell脚本的常用命令

一. 常用字符处理命令 1.1 连续打印字符seq seq打印数字&#xff1b;且只能正向打印&#xff0c;不可反向连续打印 设置打印步长 指定打印格式 1.2 反向打印字符tac cat 正向&#xff0c;tac 反向 1.3 打印字符printf printf "打印的内容"指定格式打印内容 换行…

【FlashRAG】本地部署与demo运行(二)

前文【FlashRAG】本地部署与demo运行&#xff08;一&#xff09; 下载必要的模型文件 完成了项目拉取和依赖下载后&#xff0c;我们需要进一步下载模型文件 Faiss&#xff08;Facebook AI Similarity Search&#xff09;是由Facebook AI团队开发的高效相似性搜索和密集向量聚…

火狐安装自动录制表单教程——仙盟自动化运营大衍灵机——仙盟创梦IDE

打开火狐插件页面 安装完成 使用 功能 录制浏览器操作 录入地址 开始操作 录制完成 在当今快速发展的软件开发生态中&#xff0c;自动化测试已从一种新兴技术手段&#xff0c;转变为保障软件质量与开发效率不可或缺的关键环节。其重要性体现在多个维度&#xff0c;同时&#x…

【目标检测】【AAAI-2022】Anchor DETR

Anchor DETR&#xff1a; Query Design for Transformer-Based Object Detection 锚点DETR&#xff1a;基于Transformer的目标检测查询设计 论文链接 代码链接 摘要 在本文中&#xff0c;我们提出了一种基于Transformer的目标检测新型查询设计。此前的Transformer检测器中&am…

zTasker一款Windows自动化软件,提升效率:大小仅有10MB,免费无广告

一、zTasker是什么&#xff1f; zTasker是一款发布于2023年9月的免费无广告工具&#xff0c;专为Windows用户打造。它以仅8MB的轻量体积、极低资源占用&#xff08;内存消耗不足10MB&#xff09;和秒级启动速度脱颖而出&#xff0c;堪称“任务计划程序的终极强化版”。无论是定…

数学术语之源——绝对值(absolute value)(复数模?)

目录 1. 绝对值&#xff1a;(absolute value): 2. 复数尺度(复尺度)&#xff1a;(modulus): 1. 绝对值&#xff1a;(absolute value): 一个实数的绝对值是其不考虑(irrespective)符号的大小(magnitude)。在拉丁语中具有相同意思的单词是“modulus”&#xff0c;这个单词还…

USB充电检测仪-2.USB充电检测仪硬件设计

本系列文章的最终目标是制作一个USB充电检测仪&#xff0c;支持的功能&#xff1a; 显示USB充电电压、电流、功率、充电量&#xff08;单位WH&#xff09;&#xff1b;实现Typec口和USB-A口的相互转换&#xff08;仅支持USB 2.0&#xff09;&#xff1b; 当然网上有很多卖这种…

华院计算受邀参展第九届丝绸之路国际博览会暨中国东西部合作与投资贸易洽谈会

2025年5月21日至25日&#xff0c;以“丝路融通开放合作”为主题的第九届丝绸之路国际博览会暨中国东西部合作与投资贸易洽谈会在陕西西安国际会展中心隆重召开。应上海市国内合作交流服务中心和上海科创投集团的邀请&#xff0c;华院计算技术&#xff08;上海&#xff09;股份有…

智能路由革命:AI 生态系统的智能高速交警

研究和行业基准测试揭露了一个惊人的事实&#xff1a;大多数企业的 AI 系统运行效率只有 15% 到 20%。罪魁祸首是谁呢&#xff1f;就是糟糕的查询路由。 想象一下这个现实情况&#xff1a; 你所在的组织每在 AI 上花 10 块钱&#xff0c;就有 8 块钱是浪费在把简单查询发送到…

[yolov11改进系列]基于yolov11引入倒置残差块块注意力机制iEMA的python源码+训练源码

【iEMA介绍】 iRMB&#xff08;Inverted Residual Mobile Block&#xff09;的框架原理&#xff0c;是一种结合轻量级CNN和注意力机制的方法&#xff0c;用于改进移动设备上的目标检测模型。IRMB通过倒置残差块和元移动块实现高效信息处理&#xff0c;同时保持模型轻量化。本文…

深度学习实战110-基于深度学习的工业系统故障诊断技术研究(卷积网络+注意力机制模型)

大家好,我是微学AI,今天给大家介绍一下深度学习实战110-基于深度学习的工业系统故障诊断技术研究(卷积网络+注意力机制模型)。工业系统故障诊断是确保现代工业设备安全稳定运行的关键技术环节。随着工业自动化和智能化水平的不断提高,传统故障诊断方法在应对日益复杂、多变…

Fluence (FLT) 2026愿景:RWA代币化加速布局AI算力市场

2025年5月29日&#xff0c;苏黎世 - Fluence&#xff0c;企业级去中心化计算平台&#xff0c;荣幸地揭开其2026愿景的面纱&#xff0c;并宣布将于6月1日起启动四大新举措。 Fluence 成功建立、推出并商业化了其去中心化物理基础设施计算网络&#xff08;DePIN&#xff09;&…

科学智能赋能空间科学研究(2):AI4S 范式下空间科学实验的核心挑战

中国科学院空间应用工程与技术中心在空间科学实验领域的研究覆盖了多模态空间科学实验数据模式挖掘、领域知识抽取、跨学科知识融合与认知智能等研究内容&#xff0c;有效促进了空间科学实验领域的数据应用生态的体系化建设&#xff0c;相关研究成果已正式发表于权威学术期刊《…

QML 无边框窗口翻转动画

目录 引言核心组件实现无边框翻转窗口&#xff08;FlipableDemo.qml&#xff09;登录页面和设置页面&#xff08;省略&#xff09;主界面集成&#xff08;Main.qml&#xff09; 下载链接 引言 接上篇 QML 滑动与翻转效果&#xff08;Flickable与Flipable&#xff09; 。本文通…

若依框架修改模板,添加通过excel导入数据功能

版本&#xff1a;我后端使用的是RuoYi-Vue-fast版本&#xff0c;前端是RuoYi-Vue3 需求: 我需要每个侧边栏功能都需要具有导入excel功能&#xff0c;但是若依只有用户才具备&#xff0c;我需要代码生成的每个功能都拥有导入功能。​ 每次生成一个一个改实在是太麻烦了。索性…

ECS-7000能耗监测系统能耗数据管理机

一、能耗系统介绍 能耗监测系统通过计算机和通讯网络&#xff0c;配电房的现场设备连接为一个有机的整体&#xff0c;实现电网设备运行的远程监控和集中管理。设计中充分体现系统的可用性、先进性、方便性、安全性、可靠性、可扩展性及系统性价比的合理性。 厂家&#xff1a;…