详细理解中缀表达式并实现

2023-11-03

中缀表达式的实现及概念

在这里插入图片描述
每日一笑:
公交车上,一丑女不小心踩了一个男人脚。男人大怒:你再踩一下试试,我让你好看!丑女大喜,急忙又踩了一脚道:太好了大哥,这下不用花钱整容了。

中缀表达式的定义

中缀表达式是一个通用的算术或逻辑公式表示方法。
在这里插入图片描述
中缀表达式就是我们通常所理解的数学公式或者是表达式例如:1+2/(1+1)+9*2类似这样简单的加减乘除运算的例子,我们称之为中缀表达式。
形如下图:
在这里插入图片描述
以人们的理解思路,便是以中缀形式去走的,更便于理解。但是计算机呢,大多数不是以中缀的方式去存与计算的,对于计算机来讲中缀表达式不便于理解。

中缀表达式的分解过程

例子:
在这里插入图片描述
首先我们需要两个容器来分别存放数字类型和字符类型,在这里可以选择栈这一容器,栈是先进后出,后进先出的方式,刚好满足后到先处理,根据优先级判断。

第一步: 一个符号栈operatorStack,一个数字栈numberStack,刚开始栈都为空。

在这里插入图片描述
第二步: 识别表达式第一个字符的类型,是符号就入符号栈,如果是数值行就入数字栈,显然左括号是符号,就入符号栈;
在这里插入图片描述
第三步: 接着循环下一位,判断出10为数值所以入数字栈。在这里插入图片描述
第四步: +号为字符,入字符栈
在这里插入图片描述
第五步: 20为数字,入数字栈
在这里插入图片描述
第六步: /为字符,入字符栈
在这里插入图片描述
第七步: 2为数字,入数字栈

在这里插入图片描述
第八步: *为字符,入字符栈
但是,由于符号栈的栈顶元素为/,优先级和 ✖乘法的优先级相等,但是➗在✖乘号之前 所以要先进行运算,运算之后在入栈。数字栈弹两元素先弹出的作为除数,后弹出的作为被除数。运算结果存入数字栈中。

在这里插入图片描述
最后乘号入符号栈
在这里插入图片描述

第九步: 3为数字,入数字栈
在这里插入图片描述
**第十步:**此时判断为右括号,就说明要将离右括号最近的左括号里面的数字要进行运算,运算结束之后 左括号弹栈,运算结果入栈。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第十一步: /为符号,入符号栈
在这里插入图片描述
第十二步: 2为数字入数字栈
在这里插入图片描述
第十三步: 除法的优先级高于加法,所以优先处理除法运算。
在这里插入图片描述
加法入符号栈
在这里插入图片描述
第十四步: 8为数字 进入数字栈,由于8为最后一个元素,所以要进行运算,将运算结果放入到数字栈中,此时的符号栈为空。
在这里插入图片描述
到这里中缀表达式的整个分解过程就结束了!,最后表达式的结果便是保存在数字栈中

接下来代码实现

package expression;

import java.util.Stack;

public class InfixExpression {//中缀表达式

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		String  expression = "(10+20/2*3)/2+8";
		int result = evaluteExpression(expression);
		System.out.println(result);
	}
	public static int evaluteExpression(String evaluteExpression) {
		Stack<Integer> numberStack = new Stack<>();//定义数字栈
		Stack<Character> operatorStack = new Stack<>();//定义符号栈
		evaluteExpression = formatExpression(evaluteExpression);//格式化
		String[] tokens = evaluteExpression.split(" ");//分割字符串为字符数组
		for(String token:tokens) {//遍历
			if(token.length()==0) {//如果字符数组为空直接跳过
				continue;
			}else if(token.charAt(0)=='(') {//为左括号直接入栈
				operatorStack.push('(');
			}else if(token.charAt(0)=='+'||token.charAt(0)=='-') {//为+或为-号时,都要处理符号栈里的元素
				while(!operatorStack.isEmpty()&&(operatorStack.peek()=='+'||operatorStack.peek()=='-'||
				operatorStack.peek()=='*'||operatorStack.peek()=='/')) {
					processAnOperator(operatorStack,numberStack);
				}
				operatorStack.push(token.charAt(0));
			}else if(token.charAt(0)=='*'||token.charAt(0)=='/') {//为*或为/号时,都要处理符号栈里*,/元素
				while(!operatorStack.isEmpty()&&(operatorStack.peek()=='*'||operatorStack.peek()=='/')) {
					processAnOperator(operatorStack,numberStack);
				}
				operatorStack.push(token.charAt(0));
			}else if(token.charAt(0)==')') {//为右括号时处理整个括号里的元素值
				while(operatorStack.peek()!='(') {
					processAnOperator(operatorStack,numberStack);
				}
				operatorStack.pop();
			}else {//为数值类型
				numberStack.push(new Integer(token));
			}	
		}
		while(!operatorStack.isEmpty()) {//直到符号栈不为空 一直处理
			processAnOperator(operatorStack,numberStack);
		}
		return numberStack.pop();
	}
	
	
	
	public static void processAnOperator(Stack<Character> operatorStack,Stack<Integer> numberStack) {//运算处理
		char ch = operatorStack.pop();
		int num1 = numberStack.pop();
		int num2 = numberStack.pop();
		switch(ch) {
		case '+':numberStack.push(num2+num1);break;
		case '-':numberStack.push(num2-num1);break;
		case '/':numberStack.push(num2/num1);break;
		case '*':numberStack.push(num2*num1);break;
		}
	}
	
	
	
	
	public static String formatExpression(String evaluteExpression ) {//格式化
		StringBuilder sb = new StringBuilder();
		for(int i=0;i<evaluteExpression.length();i++) {
			char c = evaluteExpression.charAt(i);
			if(c=='+'||c=='-'||
			c=='*'||c=='/'||
			 c=='('||c==')') {
				sb.append(' ');
				sb.append(c);
				sb.append(' ');
			}else {
				sb.append(c);
			}
			
		}
		
		return sb.toString();
	}

}

运行结果:
在这里插入图片描述

总结

对于中缀表达式,我们要明确两个观点 一个是需要两个栈来存储数字型元素和符号型元素,遇到符号时判断符号栈是否为空,为空直接入栈,不为空的前提下在判断运算符的优先级,在做处理。最后运算的结果保存在数字栈中,只需弹栈即可!

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

详细理解中缀表达式并实现 的相关文章

  • 在django项目里创建子路由

    首先创建一个django项目 然后开始创建子路由 创建django项目 1 在pycharm中创建一个Blog graden的django项目 注意环境要选择正确 2 在Blog graden项目的控制台中创建一个blog app 3 将t
  • BIO、NIO、AIO区别

    一 BIO NIO AIO特点 1 BIO的特点就是每次一个客户端接入 都要在服务端创建一个线程来服务于这个客户端 所以如果有很多个客户端 就会对应成千上万个服务端线程 这会导致服务端负载过高 甚至卡死 2 NIO是同步非阻塞io 客户端和

随机推荐

  • C++ opencv人脸识别框

    需求 视频实时定位人脸位置 并画框 类似效果如下 分析 取视频帧 每一帧其实就类似一张图片 利用opencv的人脸识别模块 检测每一帧并进行划线 处理完成后显示 最后组成就是动态的带人脸识别框的视频 解决方法 下面是每一帧数据的处理方法 加
  • Myeclipse破解失败&&error: unable to access jarfile cracker.jar解决方法

    我的情况是在cracker jar破解成功后 Myeclipse依旧显示不成功 破解方案如下 1 进入cmd 输入java jar cracker jar 成功则显示图形 失败则会显示 error unable to access jarf
  • 台式机安装Linux系统

    材料 台式机 U盘 内存大于8G CentOs7 步骤一 U盘启动电脑 启动成功画面 选择第一个 按E或者 Tab键 进行编辑 vmlinuz initrd initrd img inst stage2 hd LABEL CentOS x2
  • Android 10深色主题适配踩坑记录

    1 问题简述 Android 10 推出了深色主题 便于用户根据白天和夜晚自由切换合适的主题 在适配的过程中 要特别注意 切换主题会导致当前activity被重建 也就是会重新走一遍Activity的生命周期 就和横竖屏切换时会重新走生命周
  • MongoDB 日志太大

    MongoDB的日志增长的非常快 var所在的空间立即就占满了 即便换到还有一个磁盘分区保存日志 日志还是增长的非常快 磁盘眼看要告磬 有一个好办法 就是使用旋转日志 MongoDB的旋转日志有点怪 Linux下mongd服务接受一个kil
  • C++基于开源Modbus Tcp 通讯应用客户端(稳定高效,多线程后台状态读取,不卡顿)

    C 基于开源Modbus Tcp 通讯应用客户端 前言 一 演示效果 二 关键程序 1 头文件 2 源文件 三 下载链接 前言 使用多线程后台批量刷寄存器的状态 在某种程度上保证了上层接口读取的时候 不会卡顿 整体应用效果比较友好 程序应用
  • PyImport_ImportModule 返回空NULL py模块import其他库

    问题描述 执行下列代码 PyImport ImportModule 总返回空NULL Py SetPythonHome L C Program Files Python38 Py Initialize PyRun SimpleString
  • STMCubeMX5.10版本CAN使用loopback模式自测

    使用芯片 STM32F103C8T6 cube软件版本 5 10 软件包版本为 STM32Cube FW F1 V1 7 0 一 配置时钟为使用外部晶振 并配置为72M 二 使能 can 并配置参数 设置can波特率为500k 并设置为lo
  • Junit4 简单使用及示例代码

    由于新项目启动 需要引进单元测试用于项目中代码自查 小的通过网上搜集的一些资料 进行了简单整理 在此先感谢前辈们的资料提供 谢谢 junit4使用了注解进行操作 相比于junit3更为方便 对于其他框架的集成也更便于搭建 一 junit搭建
  • GitOps实践

    关注回复 学习交流群 加入 安全开发运维 答疑交流群 请朋友们 多多点击文中的广告 支持作者更新更多文章 完整原文链接 GitOps实践 云原生Tekton CI流水线 从Gitlab到镜像构建以及企业微信消息通知由于作者的工作及学习计划的
  • char与varchar的区别

    区别一 定长和变长 char 表示定长 长度固定 varchar表示变长 即长度可变 char如果插入的长度小于定义长度时 则用空格填充 varchar小于定义长度时 还是按实际长度存储 插入多长就存多长 因为其长度固定 char的存取速度
  • Spring boot开发实践(一):创建项目、打包、上传linux服务器作为service自动启动等基本过程

    一 开发工具和基本插件 vscode Extension Pack for Java Spring Boot Extension Pack 也可以用Intelij Idea 不用安装插件 本文以vscode为例 二 创建项目 参考网站 ht
  • What do pull-up transistors and pull-down transistors mean in CMOS?

    原文链接 https www quora com What do pull up transistors and pull down transistors mean in CMOS Originally Answered What is
  • el-upload上传视频,校验文件大小与格式

    视频上传之前进行校验 beforeUpload file let imgSize Number file size 1024 1024 if imgSize gt 100 this message warning 文件不能大于100MB 请
  • 分布式 - 各种机制了解下

    1 重试机制 retry 案例 httpClient 在阅读 深入分布式缓存 从原理到实践 2 2章节 2 2 7 系统重发与幂等性 以httpClient为例说明重试机制 为了减少失败次数 内部设计重试次数为3次 次数在一个私有变量中保存
  • RuntimeError: DataLoader worker (pid 28449) is killed by signal: Killed.

    可能的原因是因为内存不够用了 解决的方案有为减少number workers即可
  • Java 实现一个类似 C# as 运算符的效果

    public class AsOperator public static
  • C语言输入10名同学3门课,输入10个学生3门课的成绩,统计各科全部及格的人数(c语音)...

    编程C语言 输入n个学生成绩 计算他们的平均值并输出所有高于平均的学生成绩 include stdio h defineMAX100voidmain intmark MAX sum 0 mark 0 j 0 aver 0 printf 请输
  • 股票价值分析

    文章目录 引言 股票 股利贴现模型 DDM 股票市盈率 股份公司的经营决策 分红可能性边界 费雪分离定理 结语 引言 股票 债券和股票是最常见的金融资产 可以说是构成金融市场的基石 与债券相比 股票在期限与回报上有两点主要不同 首先除了少数
  • 详细理解中缀表达式并实现

    中缀表达式的实现及概念 每日一笑 公交车上 一丑女不小心踩了一个男人脚 男人大怒 你再踩一下试试 我让你好看 丑女大喜 急忙又踩了一脚道 太好了大哥 这下不用花钱整容了 中缀表达式的定义 中缀表达式是一个通用的算术或逻辑公式表示方法 中缀表