算法:

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

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

具体示例过程如下:

【java】中缀表达式转后缀表达式 java实现的更多相关文章

  1. 中缀表达式转后缀表达式(Java代码实现)

    后缀表达式求值 后缀表达式又叫逆波兰表达式,其求值过程可以用到栈来辅助存储.例如要求值的后缀表达式为:1 2 3 + 4 * + 5 -,则求值过程如下: 遍历表达式,遇到数字时直接入栈,栈结构如下 ...

  2. Java堆栈的应用2----------中缀表达式转为后缀表达式的计算Java实现

    1.堆栈-Stack 堆栈(也简称作栈)是一种特殊的线性表,堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置进行插入和删除操作,而堆栈只允许在固定一端进行插入和删除 ...

  3. 数据结构Java实现06----中缀表达式转换为后缀表达式

    本文主要内容: 表达式的三种形式 中缀表达式与后缀表达式转换算法 一.表达式的三种形式: 中缀表达式:运算符放在两个运算对象中间,如:(2+1)*3.我们从小做数学题时,一直使用的就是中缀表达式. 后 ...

  4. .net表达式计算器(中缀表达式转后缀表达式,支持20多个数学函数,支持函数嵌套)

    最近在网上查了一下表达工计算器的类库,发现Java版本的有一个比较成熟的叫W3EVal,好像是一个IBM工程师写的,.net就很少了(可能是我了解不够多),但投机取巧的实现思路有很多,比如: (1)将 ...

  5. 利用stack结构,将中缀表达式转换为后缀表达式并求值的算法实现

    #!/usr/bin/env python # -*- coding: utf-8 -*- # learn <<Problem Solving with Algorithms and Da ...

  6. RPN-逆波兰计算器-中缀表达式转后缀表达式-javascript

    1.利用栈(Stack)来存储操作数和操作符: 2.包含中缀表达式转后缀表达式的函数,这个是难点,也是关键点: 2.1.将输入字符串转为数组: 2.2.对转换来的字符进行遍历:创建一个数组,用来给存储 ...

  7. 练习3.20 a 将中缀表达式转换为后缀表达式

    //将中缀表达式转换为后缀表达式 int main() { ; ]={,,,,,,,}; char tmp; PtrToStack s; s = CreateStack( MaxSize ); ) { ...

  8. NYOJ--257--郁闷的C小加(一)(中缀表达式变后缀表达式 )

    郁闷的C小加(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 我们熟悉的表达式如a+b.a+b*(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说 ...

  9. hdu-1237 简单计算器---中缀表达式转后缀表达式

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1237 题目大意: 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值. 思路 ...

随机推荐

  1. Windows 安装 MySQL 8.0.11

    下载并解压 从官方网站下载最新安装包 解压到目标安装目录 新建配置文件 在安装目录新建my.ini文件 添加如下内容(需修改为自己的配置) #----------------------------- ...

  2. es6 入坑笔记(一)---let,const,解构,字符串模板

    let  全面取代var 大概相似于C++的定义,一个变量必须得先定义后使用,没有预编译 注意let的作用域,一个{}就是一个作用域,上述规则须在一个作用于内 坑:for(let i =0;i < ...

  3. php实现姓名按首字母排序的类与方法

    php将名字按首字母进行排序 <?php public function getFirstChar($s){ $s0 = mb_substr($s,0,3); //获取名字的姓 $s = ico ...

  4. 【JVM】TroubleShooting之内存溢出异常(OOM)与调优

    1. OOM概述 If your application's execution time becomes longer and longer, or if the operating system ...

  5. vue 解决跨域问题

    1.后端处理允许跨域 2.反向代理跨域 代理服务器英文全称是Proxy Server,其功能就是代理网络用户去去的网络信息.形象的说:它是网络信息的中转站. vue中设置代理: 1.config/in ...

  6. Linux入门第五天——shell脚本入门(中)基础语法之判断与条件

    一.判断式 利用 test 命令进行执行结果的判断(例如判断是否存在该文件):关于test  test:test 示例:结合回传值 $? 进行判断:关于$?:$? [root@localhost tm ...

  7. 20155220 实验三 敏捷开发与XP实践 实验报告

    20155220 实验三 敏捷开发与XP实践 实验报告 实验内容 XP基础 XP核心实践 相关工具 实验要求 没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim ...

  8. echarts设置小图标位置

    // <!-- 左上角小图标 --> toolbox: { show : true, // orient: 'horizontal', // 布局方式,默认为水平布局,可选为: // // ...

  9. echarts 去掉上面的小图标

    在option里找到toolbox,删除对应的代码即可: toolbox: { y : -30, show : true, feature : { mark : '辅助线开关', markUndo : ...

  10. 单线程的redis为什么吞吐量可以这么大

    原文:单线程的redis为什么吞吐量可以这么大 一.Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了很多上下文切换线程的时间: 3.r ...