【Java】中缀表达式转后缀表达式和后缀表达式四则运算求值

过程概述

中缀表达式转后缀表达式过程概述:从左到右遍历中缀表达式,若是数字就输出成为后缀表达式的一部分;若是符号,则判断其与栈顶符号的优先级,是右括号或优先级不高于栈顶符号(乘除取模优先加减)则栈顶元素依次出栈并输出,并将当前符号进栈,一直到输出后缀表达式为止。

后缀表达式四则运算求值过程概述:从左到右遍历后缀表达式,若是数字就进栈,若是符号,将处于栈顶两个数字出栈,用该符号运算,运算结果进栈,最后栈中剩下的就是最终结果。

代码实现

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;/*** 用List集合来装后缀表达式,可以进行多位数的四则运算*/
public class CalculatorPlus {public static List<String> infixToPostfix(String infixExpression){Stack<Character> operatorStack=new Stack<>();List<String> postfixExpression=new ArrayList<>();for(int i=0;i<infixExpression.length();i++){//如果是数字if(Character.isDigit(infixExpression.charAt(i))){//可能是多位的数StringBuilder temp=new StringBuilder();temp.append(infixExpression.charAt(i));while (++i<infixExpression.length()&&Character.isDigit(infixExpression.charAt(i))){temp.append(infixExpression.charAt(i));}postfixExpression.add(temp.toString());i--;//while判断完后,i多往后挪了一位,所以要-1}//如果是左括号else if(infixExpression.charAt(i)=='('){operatorStack.push(infixExpression.charAt(i));}//如果是右括号,去匹配左括号else if(infixExpression.charAt(i)==')'){while (!operatorStack.empty()&&operatorStack.peek()!='('){postfixExpression.add(operatorStack.pop()+"");}operatorStack.pop();}//如果是+-*/else {//将优先级<=当前运算符优先级的运算符pop出来,追加到后缀表达式中while (!operatorStack.empty()&&getPrecedence(infixExpression.charAt(i))<=getPrecedence(operatorStack.peek())){postfixExpression.add(operatorStack.pop()+"");}operatorStack.push(infixExpression.charAt(i));}}//将栈中剩余的运算符依次pop出来追加到结果中while (!operatorStack.empty()){postfixExpression.add(operatorStack.pop()+"");}return postfixExpression;}public static int evaluatePostfix(List<String> postfixExpression){Stack<Integer> stack=new Stack<>();//放用来计算的数字//从左至右遍历后缀表达式for(String s:postfixExpression){//如果是数值if(s.charAt(0)>=48&&s.charAt(0)<=57){stack.push(Integer.valueOf(s));}else {//如果是运算符switch (s){case "+":stack.push(stack.pop()+stack.pop());break;case "-"://pop1是被减数,pop2是减数,先pop出来的是减数/*2    -  1    =  1被减数  减数   差           /和%类似*/Integer pop2 = stack.pop();Integer pop1 = stack.pop();stack.push(pop1-pop2);break;case "*":stack.push(stack.pop()*stack.pop());break;case "/":Integer pop4 = stack.pop();Integer pop3 = stack.pop();stack.push(pop3/pop4);break;case "%":Integer pop6 = stack.pop();Integer pop5 = stack.pop();stack.push(pop5%pop6);break;default:throw new IllegalArgumentException("无效的运算符:"+s);}}}// 栈顶元素即为最终结果return stack.pop();}//在中缀转后缀时要判断符号优先级private static int getPrecedence(char operator) {switch (operator) {case '+':case '-':return 1;case '*':case '/':case '%':return 2;default:return 0;}}
}

tips

 栈在两个地方的作用:

 中缀表达式转后缀表达式时用栈存放运算符,后缀表达式四则运算求值时用栈存放操作数

另外

第一次实现该算法的时候,没有考虑到多位数,只能实现一位数的四则运算,但对理解原理也有帮助,如果上面的用List集合看不明白的话可以先理解理解下面的再去看上面的:

import java.util.Stack;/*** 只能实现一位数的四则运算*/
public class Calculator {//中缀表达式转后缀表达式public static String infixToPostfix(String infixExpression){StringBuilder postfixExpression=new StringBuilder();Stack<Character> operatorStack=new Stack<>();   //用来存放运算符//从左至右依次遍历中缀表达式for(char c:infixExpression.toCharArray()){//如果是数字if(Character.isDigit(c)){postfixExpression.append(c);//如果是(}else if(c=='('){operatorStack.push(c);//如果是)}else if(c==')'){//一直pop,直到匹配到(while (!operatorStack.empty()&&operatorStack.peek()!='('){//将过程中pop出来的运算符追加到后缀表达式中postfixExpression.append(operatorStack.pop());}//如果是+-*/%}else {//将优先级<=当前运算符优先级的运算符pop出来,追加到后缀表达式中while (!operatorStack.empty()&&getPrecedence(c)<=getPrecedence(operatorStack.peek())){postfixExpression.append(operatorStack.pop());}//将当前运算符进栈operatorStack.push(c);}}//将栈中剩余的运算符依次pop出来追加到结果中while (!operatorStack.empty()){postfixExpression.append(operatorStack.pop());}return postfixExpression.toString();}//后缀表达式求值public static int evaluatePostfix(String postfixExpression){Stack<Integer> stack=new Stack<>();//放用来计算的数字//从左至右遍历后缀表达式for(int i=0;i<postfixExpression.length();i++){if(Character.isDigit(postfixExpression.charAt(i))){//如果是数字stack.push(Character.getNumericValue(postfixExpression.charAt(i)));}else{//如果是运算符,弹出栈顶两个元素进行计算,然后将结果推入栈//注意-,/,%的运算数顺序,谁是减数,谁是被减数switch (postfixExpression.charAt(i)){case '+':stack.push(stack.pop()+stack.pop());break;case '-'://pop1是被减数,pop2是减数,先pop出来的是减数/*2    -  1    =  1被减数  减数   差           /和%类似*/Integer pop2 = stack.pop();Integer pop1 = stack.pop();stack.push(pop1-pop2);break;case '*':stack.push(stack.pop()*stack.pop());break;case '/':Integer pop4 = stack.pop();Integer pop3 = stack.pop();stack.push(pop3/pop4);break;case '%':Integer pop6 = stack.pop();Integer pop5 = stack.pop();stack.push(pop5%pop6);break;default:throw new IllegalArgumentException("无效的运算符:"+postfixExpression.charAt(i));}}}// 栈顶元素即为最终结果return stack.pop();}//在中缀转后缀时要判断符号优先级private static int getPrecedence(char operator){switch (operator){case '+':case '-':return 1;case '*':case '/':case '%':return 2;default:return 0;}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/168553.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式篇---第五篇

系列文章目录 文章目录 系列文章目录前言一、你知道哪些限流算法?二、说说什么是计数器(固定窗口)算法三、说说什么是滑动窗口算法前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去…

二维数值型数组例题2

1、内部和 题目描述 给定一个m行n列的二维矩阵&#xff0c;求其内部元素和 输入要求 第一行为两个整数&#xff1a;m和n&#xff08;0<m,n<10&#xff09;&#xff0c;接下来输入m*n的二维矩阵 输出要求 二维矩阵内部元素和 输入样例 3 3 1 2 3 4 5 6 7 8 9 …

android ffmpeg

参考 1、ijkplayer 2、GitHub - tanersener/mobile-ffmpeg: FFmpeg for Android, iOS and tvOS. Not maintained anymore. Superseded by FFmpegKit. https://github.com/mucephi/ffplay/tree/main GitHub - mandroidstudy/FFPlayer: 基于FFmpeg的播放器 视频缓存库&#…

RK3399 板子烧录Armbian

本来不想写在CSDN这里的。帮有需要的同学了吧。 板子上面标记型号为&#xff1a; GC18-108-RK3399-V2.0TEAN E120339 94V-OML1没有HDMI接口&#xff08;我也是汗&#xff0c;买的时候注意到&#xff0c;坑了&#xff09;&#xff0c;配置信息。 CPU : RK3399RAMROM: 4G16G无…

DNS 区域传输 (AXFR)

漏洞描述 docker环境搭建 使用 AXFR 协议的 DNS 区域传输是跨 DNS 服务器复制 DNS 记录的最简单机制。为了避免在多个 DNS 服务器上编辑信息&#xff0c;可以在一台服务器上编辑信息&#xff0c;并使用 AXFR 将信息复制到其他服务器。但是&#xff0c;如果您不保护您的服务器&…

JavaScript 数据类型转换

JavaScript 数据类型转换 目录 JavaScript 数据类型转换 一、类型转换简介 1、字符串型转换为数值型 2、数值型转换为字符串型 一、类型转换简介 所谓的类型转换&#xff0c;就是将一种数据类型转换为另外一种数据类型&#xff0c;例如上一节课说到的&#xff0c;如果一个…

【web】Fastapi自动生成接口文档(Swagger、ReDoc )

简介 FastAPI是流行的Python web框架&#xff0c;适用于开发高吞吐量API和微服务&#xff08;直接支持异步编程&#xff09; FastAPI的优势之一&#xff1a;通过提供高级抽象和自动数据模型转换&#xff0c;简化请求数据的处理&#xff08;用户不需要手动处理原始请求数据&am…

pgz easyexcel如何给excel文件添加自定义属性

免费API方式 直接上传URL,自定义修改Excel 视频演示【内含接口地址】 https://www.ixigua.com/7304510132812153385 前情提示 | 功能说明 多选仅支持微软office、office365系列Excel。因为WPS宏功能需要企业版且付费生成xlsx、xlsm等文件,office和WPS均可以打开,均可以单…

【开源】基于微信小程序的智慧家政系统

项目编号&#xff1a; S 063 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S063&#xff0c;文末获取源码。} 项目编号&#xff1a;S063&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询家政服…

Docker create命令

docker create &#xff1a;创建一个新的容器但不启动它。 用法同docker run 语法 docker create [OPTIONS] IMAGE [COMMAND] [ARG...]语法同docker run 实例 使用docker镜像nginx:latest创建一个容器&#xff0c;并将容器命名为myProject docker create --name myProje…

随便问问webtab的记录(1)

Q1.我们是一个具有软硬件研发能力的公司&#xff0c;下一个要开发的产品是汽车行业ADAS的硬件在环仿真系统&#xff0c;包括硬件和软件还有算法&#xff0c;请帮我做一个详细的产品分析&#xff0c;还有产品的设计说明. 开发汽车行业的ADAS&#xff08;高级驾驶辅助系统&#…

C#,《小白学程序》第十四课:随机数(Random)第一,几种随机数的计算方法与代码

1 文本格式 /// <summary> /// 《小白学程序》第十四课&#xff1a;随机数&#xff08;Random&#xff09;第一&#xff0c;几种随机数的计算方法与代码 /// 本课初步接触一下随机数。 /// </summary> /// <param name"sender"></param> ///…

Bytebase 2.11.1 - 数据脱敏支持语义类型和脱敏算法

&#x1f680; 新功能 数据脱敏支持自定义脱敏算法和语义类型。 &#x1f514; 重大变更 用户页面的 URL 由 /u/{uid} 变更为 /users/{email}。工作空间的所有者和开发者分别更名为&#xff1a;管理员和成员。 &#x1f384; 改进 SQL 编辑器支持显示表的 DDL 语句&#…

Vue3-新特性defineOptions和defineModel

defineOptions 问题&#xff1a;用了<script setup>后&#xff0c;就无法添加与其平级的属性了&#xff0c;比如定义组件的name或其他自定义的属性。 为了解决这一问题&#xff0c;引入了defineProps与defineEmits这两个宏&#xff0c;但这只解决了props与emits这两个属…

AD9361纯逻辑控制从0到1连载10-多芯片同步MCS以及射频同步方法

本文基于ZC706FMCOMMS5的平台&#xff0c;介绍了AD9361的多芯片同步设计方法。这里的“同步”包含了基带同步以及射频同步。AD9361原生只支持基带同步&#xff0c;官方的名称叫MCS&#xff08;Multi-chip Baseband Synchronization &#xff09;&#xff0c;实际上配合外围的射…

【Mybatis-Plus篇】Mybatis-Plus基本使用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

7-22 龟兔赛跑

import java.util.Scanner; class Main {public static void main(String[] args) {Scanner scnew Scanner(System.in);int timesc.nextInt();sc.close();int wugui 0;//乌龟里程int tuzi 0;//兔子里程int tuzi_run0;int tuzi_rest0;int is_rest0;//是否需要休息&#xff1a;…

鸿蒙原生应用/元服务开发-AGC分发如何上架HarmonyOS应用

一、上架整体流程 二、上架HarmonyOS应用 获取到HarmonyOS应用软件包后&#xff0c;开发者可将应用提交至AGC申请上架。上架成功后&#xff0c;用户即可在华为应用市场搜索获取开发者的HarmonyOS应用。 配置应用信息 1.登录AppGallery Connect&#xff0c;选择“我的应用”。…

C#,《小白学程序》第十七课:随机数(Random)第四,移动平均值(Moving Average)的计算方法与代码

1 文本格式 /// <summary> /// 《小白学程序》第十七课&#xff1a;随机数&#xff08;Random&#xff09;第四&#xff0c;移动平均值的计算方法与代码 /// 继续学习数据统计&#xff0c;移动平均值的计算方法 /// 移动平均值就是一定步长内数值的平均值&#xff0c;用…

解决:javax.websocket.server.ServerContainer not available 报错问题

原因&#xff1a; 用于扫描带有 ServerEndpoint 的注解成为 websocket&#xff0c;该方法是 服务器端点出口&#xff0c;当进行 SpringBoot 单元测试时&#xff0c;并没有启动服务器&#xff0c;所以当加载到这个bean时会报错。 解决方法&#xff1a; 加上这个注解内容 Spr…