【java】中缀表达式转后缀表达式 java实现

简介: 算法:中缀表达式转后缀表达式的方法:1.遇到操作数:直接输出(添加到后缀表达式中)2.栈为空时,遇到运算符,直接入栈3.遇到左括号:将其入栈4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。

算法:

中缀表达式转后缀表达式的方法:
1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素【栈内的栈顶运算符>=遇到的运算符,就弹出】,然后将该运算符入栈
6.最终将栈中的元素依次出栈,输出。

 

例如:【5+4*6/2+3+(4*5)/5】 =24

转化之后的后缀表达式:【5 4 6 * 2 / + 3 + 4 5 *5 / +】

 

下面使用java实现 中缀表达式转化后缀表达式。  【支持多位数字,支持小数,支持+-*/()运算符】

  1 package com.agen.exchangePox;
  2 
  3 import java.util.ArrayList;
  4 import java.util.Arrays;
  5 import java.util.HashMap;
  6 import java.util.List;
  7 import java.util.Map;
  8 import java.util.stream.Collectors;
  9 
 10 import org.junit.Test;
 11 
 12 public class InfixInToSuffix {
 13     /**
 14      *提前将 符号的优先级定义好
 15      */
 16     private static final Map<Character, Integer> basic = new HashMap<Character, Integer>();
 17     static {
 18         basic.put('-', 1);
 19         basic.put('+', 1);
 20         basic.put('*', 2);
 21         basic.put('/', 2);
 22         basic.put('(', 0);//在运算中  ()的优先级最高,但是此处因程序中需要 故设置为0
 23     }
 24     
 25     @Test
 26     public void test(){
 27         String a = toSuffix("55.6+4*60/2+33+(4.7*5.6)/5");//传入 一串 算数公式  
 28         System.out.println(a);
 29         System.out.println(dealEquation(a));
 30         
 31         
 32     }
 33     
 34     /**
 35      * 将  中缀表达式  转化为  后缀表达式
 36      */
 37     public String toSuffix(String infix){
 38         List<String> queue = new ArrayList<String>();                                    //定义队列  用于存储 数字  以及最后的  后缀表达式
 39         List<Character> stack = new ArrayList<Character>();                             //定义栈    用于存储  运算符  最后stack中会被 弹空
 40         
 41         char[] charArr = infix.trim().toCharArray();                                    //字符数组  用于拆分数字或符号
 42         String standard = "*/+-()";                                                        //判定标准 将表达式中会出现的运算符写出来
 43         char ch = '&';                                                                    //在循环中用来保存 字符数组的当前循环变量的  这里仅仅是初始化一个值  没有意义
 44         int len = 0;                                                                    //用于记录字符长度 【例如100*2,则记录的len为3 到时候截取字符串的前三位就是数字】
 45         for (int i = 0; i < charArr.length; i++) {                                        //开始迭代
 46             
 47             ch = charArr[i];                                                            //保存当前迭代变量
 48             if(Character.isDigit(ch)) {                                                    //如果当前变量为 数字  
 49                 len++;    
 50             }else if(Character.isLetter(ch)) {                                            //如果当前变量为  字母
 51                 len++;
 52             }else if(ch == '.'){                                                        //如果当前变量为  .  会出现在小数里面
 53                 len++;
 54             }else if(Character.isSpaceChar(ch)) {                                        //如果当前变量为 空格  支持表达式中有空格出现
 55                 if(len > 0) {                                                            //若为空格 代表 一段结束 ,就可以往队列中  存入了  【例如100 * 2  100后面有空格 就可以将空格之前的存入队列了】
 56                     queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i)));    //往 队列存入 截取的 字符串 
 57                     len = 0;                                                            //长度置空
 58                 }
 59                 continue;                                                                //如果空格出现,则一段结束  跳出本次循环
 60             }else if(standard.indexOf(ch) != -1) {                                        //如果是上面标准中的 任意一个符号
 61                 if(len > 0) {                                                            //长度也有
 62                     queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i)));    //说明符号之前的可以截取下来做数字
 63                     len = 0;                                                            //长度置空
 64                 }
 65                 if(ch == '(') {                                                            //如果是左括号
 66                     stack.add(ch);                                                        //将左括号 放入栈中
 67                     continue;                                                            //跳出本次循环  继续找下一个位置
 68                 }
 69                 if (!stack.isEmpty()) {                                                    //如果栈不为empty
 70                     int size = stack.size() - 1;                                        //获取栈的大小-1  即代表栈最后一个元素的下标
 71                     boolean flag = false;                                                //设置标志位
 72                     while (size >= 0 && ch == ')' && stack.get(size) != '(') {            //若当前ch为右括号,则 栈里元素从栈顶一直弹出,直到弹出到 左括号
 73                         queue.add(String.valueOf(stack.remove(size)));                    //注意此处条件:ch并未入栈,所以并未插入队列中;同样直到找到左括号的时候,循环结束了,所以左括号也不会放入队列中【也就是:后缀表达式中不会出现括号】
 74                         size--;                                                            //size-- 保证下标永远在栈最后一个元素【栈中概念:指针永远指在栈顶元素】
 75                         flag = true;                                                    //设置标志位为true  表明一直在取()中的元素
 76                     }
 77                     while (size >= 0 && !flag && basic.get(stack.get(size)) >= basic.get(ch)) {    //若取得不是()内的元素,并且当前栈顶元素的优先级>=对比元素 那就出栈插入队列
 78                         queue.add(String.valueOf(stack.remove(size)));                    //同样  此处也是remove()方法,既能得到要获取的元素,也能将栈中元素移除掉
 79                         size--;
 80                     }
 81                 }
 82                 if(ch != ')') {                                                            //若当前元素不是右括号  
 83                     stack.add(ch);                                                        //就要保证这个符号 入栈
 84                 } else {                                                                //否则就要出栈 栈内符号
 85                     stack.remove(stack.size() - 1);
 86                 }
 87             }
 88             if(i == charArr.length - 1) {                                                //如果已经走到了  中缀表达式的最后一位
 89                 if(len > 0) {                                                            //如果len>0  就截取数字
 90                     queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len+1, i+1)));
 91                 }    
 92                 int size = stack.size() - 1;                                            //size表示栈内最后一个元素下标
 93                 while (size >= 0) {                                                        //一直将栈内  符号全部出栈 并且加入队列中  【最终的后缀表达式是存放在队列中的,而栈内最后会被弹空】
 94                     queue.add(String.valueOf(stack.remove(size)));
 95                     size--;
 96                 }
 97             }
 98             
 99         }
100         return queue.stream().collect(Collectors.joining(","));                            //将队列中元素以,分割 返回字符串
101     }
102     
103 
104     /**
105      * 将 后缀表达式 进行  运算 计算出结果
106      * @param equation
107      * @return
108      */
109     public String dealEquation(String equation){
110         String [] arr = equation.split(",");                                    //根据, 拆分字符串
111         List<String> list = new ArrayList<String>();                            //用于计算时  存储运算过程的集合【例如list中当前放置  100   20  5  /  则取出20/5 最终将结果4存入list   此时list中结果为  100  4 】
112         
113         
114         for (int i = 0; i < arr.length; i++) {                                    //此处就是上面说的运算过程, 因为list.remove的缘故,所以取出最后一个数个最后两个数  都是size-2
115             int size = list.size();
116             switch (arr[i]) {
117             case "+": double a = Double.parseDouble(list.remove(size-2))+ Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(a));     break;
118             case "-": double b = Double.parseDouble(list.remove(size-2))- Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(b));     break;
119             case "*": double c = Double.parseDouble(list.remove(size-2))* Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(c));     break;
120             case "/": double d = Double.parseDouble(list.remove(size-2))/ Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(d));       break;
121             default: list.add(arr[i]);     break;                                    //如果是数字  直接放进list中
122             }
123         }
124         
125         return list.size() == 1 ? list.get(0) : "运算失败" ;                    //最终list中仅有一个结果,否则就是算错了
126     }
127     
128     
129 
130 }

 

 

其中的解释比较详细,不再赘述!!!

具体示例过程如下:

 

相关文章
|
5天前
|
Java
探索Java中的Lambda表达式
【10月更文挑战第37天】本文将带你深入理解Java的Lambda表达式,从基础语法到高级特性,通过实例讲解其在函数式编程中的应用。我们还将探讨Lambda表达式如何简化代码、提高开发效率,并讨论其在实际项目中的应用。
|
7天前
|
Java API
Java中的Lambda表达式与函数式编程####
【10月更文挑战第29天】 本文将深入探讨Java中Lambda表达式的实现及其在函数式编程中的应用。通过对比传统方法,我们将揭示Lambda如何简化代码、提高可读性和维护性。文章还将展示一些实际案例,帮助读者更好地理解和应用Lambda表达式。 ####
|
7天前
|
JSON 自然语言处理 Java
这款轻量级 Java 表达式引擎,真不错!
AviatorScript 是一个高性能、轻量级的脚本语言,基于 JVM(包括 Android 平台)。它支持数字、字符串、正则表达式、布尔值等基本类型,以及所有 Java 运算符。主要特性包括函数式编程、大整数和高精度运算、完整的脚本语法、丰富的内置函数和自定义函数支持。适用于规则判断、公式计算、动态脚本控制等场景。
|
12天前
|
Java API 开发者
Java中的Lambda表达式与函数式编程####
在Java的演变过程中,Lambda表达式和函数式编程的引入无疑是一次重大的飞跃。本文将深入探讨Lambda表达式的定义、用法及优势,并结合实例说明如何在Java中利用Lambda表达式进行函数式编程。通过对比传统编程方式,揭示Lambda表达式如何简化代码、提高开发效率和可维护性。 ####
|
21天前
|
自然语言处理 安全 Java
Aviator Java 表达式引擎
AviatorScript 是一门高性能、轻量级寄宿于 JVM 之上的脚本语言。
40 10
|
18天前
|
Java API 数据处理
探索Java中的Lambda表达式与Stream API
【10月更文挑战第22天】 在Java编程中,Lambda表达式和Stream API是两个强大的功能,它们极大地简化了代码的编写和提高了开发效率。本文将深入探讨这两个概念的基本用法、优势以及在实际项目中的应用案例,帮助读者更好地理解和运用这些现代Java特性。
|
1月前
|
Java 数据库
案例一:去掉数据库某列中的所有英文,利用java正则表达式去做,核心:去掉字符串中的英文
这篇文章介绍了如何使用Java正则表达式从数据库某列中去除所有英文字符。
46 15
|
22天前
|
Java API
[Java]Lambda表达式
本文主要介绍了Java中的Lambda表达式,包括其优化匿名内部类的方式、使用规范、内置函数式接口及方法引用等内容。文章详细解析了Lambda的基础语法、参数列表、方法体的简化规则,以及如何利用Lambda优化代码。此外,还探讨了Lambda的作用域和引用规则,强调了对局部变量、成员变量和常量的访问限制,旨在帮助读者全面理解和掌握Lambda表达式的应用。
13 0
[Java]Lambda表达式
|
1月前
|
Java 程序员 API
Java中的Lambda表达式:简化代码的秘密武器
【10月更文挑战第11天】 在Java编程中,Lambda表达式是一种简洁而强大的工具,它允许我们将函数作为参数传递给其他方法。本文将介绍Lambda表达式的基本概念、使用方法以及在实际项目中的应用案例,帮助你更好地理解和利用这一特性来简化代码。
22 8
|
1月前
|
并行计算 Java API
Java中的Lambda表达式及其应用
本文将深入探讨Java中的Lambda表达式,从基本概念到实际应用。我们将了解Lambda表达式的定义、优势和使用场景,并通过实例展示其在Java编程中的强大功能。无论是初学者还是经验丰富的开发者,都可以从中获得有价值的见解。