/*

中缀表达式转成后缀表达式 "12+((22+31)*4)-5" ==> 12 22 31 + 4 * + 5 -

第一步,将中缀表达式转成中缀字符串list,方便遍历 [12, +, (, (, 22, +, 31, ), *, 4, ), -, 5]

第二步,将中缀字符串list转成后缀表达式对应的list [12, +, (, (, 22, +, 31, ), *, 4, ), -, 5] -> [12, 22, 31, +, 4, *, +, 5, -]

具体步骤:

初始化两个栈,s1运算符栈,s2存储中间结果的栈

遍历中缀表达式字符串list

若是数字,直接入栈s2;

若是"(",直接入栈s1;

若是")",依次弹出符号栈s1的栈顶运算符,并入栈s2,直到遇到左括号,将左括号再出栈,把一对括号消除掉;

若是操作符(加减乘除),比较它和s1栈顶操作符的优先级大小:

a.若s1为空,或者栈顶运算符为"(",则直接将此运算符入栈;

b.否则,若其优先级比栈顶运算符的优先级高,也将此运算符入栈;

c.否则,将s1栈顶的运算符弹出,并入栈到s2中,继续从a循环。

遍历结束后,把s1中剩余的运算符依次弹出,并加入s2。

依次弹出s2中的元素,结果的逆序即为中缀表达式对应的后缀表达式。

*/

public class InfixToPostfixDemo {

// 第1步. 将中缀表达式转成中缀字符串列表,方便遍历。

// "12+((22+31)*4)-5" ==> [12, +, (, (, 22, +, 31, ), *, 4, ), -, 5]

public List toInfixList(String exp) {

List res = new ArrayList<>();

int i = 0;

// 保存遍历过程中产生的数字,连续的数字字符拼接成一个数

StringBuilder sb = new StringBuilder();

while (i < exp.length()) {

if (!Character.isDigit(exp.charAt(i))) {

res.add(exp.charAt(i) + ""); // 如果当前字符不是数字,直接加入结果

i++;

} else {

sb.delete(0, sb.length());// 先清除

while (i < exp.length() && Character.isDigit(exp.charAt(i))) {

sb.append(exp.charAt(i));

i++;

}

res.add(sb.toString());

}

}

return res;

}

// 第2步 将中缀表达式字符串列表,转成后缀表达式字符串列表.

// [12, +, (, (, 22, +, 31, ), *, 4, ), -, 5] -> [12, 22, 31, +, 4, *, +, 5, -]

public List toPostList(List list) {

Stack s1 = new Stack<>(); // 符号栈

// 存储中间结果

List s2 = new ArrayList<>(); // 在整个转换过程中,没有pop操作,在后面还要逆序输出,所以用list代替栈

for (String item : list) {

if (item.matches("\\d+")) s2.add(item); // 如果是数字,加入s2

else if (item.equals("(")) s1.push(item); // 如果是左括号,入栈s1

else if (item.equals(")")) { // 如果是右括号,则依次弹出符号栈s1栈顶的运算符,并压入s2,直到遇到左括号位置,将这一对括号消除掉

while (!s1.peek().equals("(")) {

s2.add(s1.pop());

}

s1.pop(); // 丢弃左括号,继续循环,也就消除了一对括号

} else { // 此时,遇到的是加减乘除运算符

// 当前操作符优先级<=s1的栈顶运算符的优先级,则将s1的运算符弹出,并加入到s2中

while (!s1.empty() && priority(s1.peek()) >= priority(item)) s2.add(s1.pop());

s1.push(item);

}

}

// 将s1中剩余的运算符依次弹出,并加入s2

while (!s1.empty()) {

s2.add(s1.pop());

}

return s2;

}

private int priority(String op) {

if ("+".equals(op) || "-".equals(op)) return 1;

if ("*".equals(op) || "/".equals(op)) return 2;

return 0; // 如果是左括号返回0

}

// 对后缀表达式字符串列表进行计算

public double calculatePoland(List list) {

Stack stack = new Stack<>();

for (String s : list) {

double n1, n2;

switch (s) {

case "*":

n1 = stack.pop();

n2 = stack.pop();

stack.push(n1 * n2);

break;

case "/":

n1 = stack.pop();

n2 = stack.pop();

stack.push(n2 / n1);

break;

case "+":

n1 = stack.pop();

n2 = stack.pop();

stack.push(n1 + n2);

break;

case "-":

n1 = stack.pop();

n2 = stack.pop();

stack.push(n2 - n1);

break;

default:

stack.push(Double.parseDouble(s));

break;

}

}

return stack.pop();

}

public static void main(String[] args) {

String exp = "12+((22+31)*4)-5";

InfixToPostfixDemo app = new InfixToPostfixDemo();

List infixList = app.toInfixList(exp); // 第1步

List postList = app.toPostList(infixList); // 第2步

double res = app.calculatePoland(postList); //第3步

System.out.println(infixList);

System.out.println(postList);

System.out.println(res);

}

}

中缀表达式转后缀表达式 java_中缀表达式转后缀表达式并计算结果Java实现相关推荐

  1. 数据结构 - 栈 (逆波兰计算器)(栈的三种表达式)(前缀、中缀和后缀表达式,后缀也叫逆波兰表达式)(中缀表达式转后缀表达式实现步骤及完整代码)

    栈的三种表达式:前缀.中缀和后缀表达式,后缀也叫逆波兰表达式 前缀(波兰表达式) 中缀(对人来讲很好理解,对于计算机来讲就方便了,一般会把中缀表达式转换成后缀表达式) 后缀(逆波兰表达式) 计算过程 ...

  2. 算术表达式的前缀式、中缀式、后缀式相互转换

    中缀表达式(中缀记法) 中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间.中缀表达式是人们常用的算术表示方法. 虽然人的大脑很容易理解与分析中缀表达式,但对计算机来说中缀 ...

  3. 中缀表达式X=A+B*(C-(D+F))/E转后缀表达式之后是什么?

    中缀表达式X=A+B*(C-(D+F))/E转后缀表达式之后是什么? ABCDF+-*E/+ ABDF+C-*E/+ ABDF+C*-E/+ ABDF+C*-E+/ 正确答案:A A+B*(C-(D+ ...

  4. C++代码实现中缀表达式求值(基于中缀表达式转后缀表达式)

    C++代码实现中缀表达式求值(基于中缀表达式转后缀表达式) 样例输入:3*(2+5) 样例输出:21 代码:#include <bits/stdc++.h> using namespace ...

  5. 栈运算 java_栈的应用——四则运算表达式求值(Java实现)

    首先介绍几个概念 中缀式:平常我们所用到的标准的四则运算表达式就是中缀式,如9+(3-1)*3+10/2,这就是一个中缀式 后缀式(逆波兰式):一种不需要括号的后缀表达法,我们也把他称为逆波兰式,如将 ...

  6. 前缀后缀表达式 表达式X=A+B*(C-D)/E+F的后缀表示形式可以为( )

    使用方法:https://blog.csdn.net/whatforever/article/details/6738538 a+bc-(d+e) 第一步:按照运算符的优先级对所有的运算单位加括号~ ...

  7. 表达式求值(最详细分析+代码实现+表达式之间的相互转换)

    目录 一.概念 二.前缀表达式的逻辑和实现方式 1.定义 2.前缀表达式的计算机求值 3.例子 4.代码实现 三.中缀表达式的逻辑和实现方式 1.定义 2.中缀表达式规则 3.中缀表达式的计算机求值 ...

  8. 信息学奥赛一本通 1962:【13NOIP普及组】表达式求值 | 洛谷 P1981 [NOIP2013 普及组] 表达式求值

    [题目链接] ybt 1962:[13NOIP普及组]表达式求值 洛谷 P1981 [NOIP2013 普及组] 表达式求值 [题目考点] 栈 中缀表达式转后缀表达式,后缀表达式求值 中缀表达式求值 ...

  9. C语言表达式的求解规则,C语言实现整数四则运算表达式的计算

    一.问题重述 [问题描述] 从标准输入中读入一个整数算术运算表达式,如5 - 1 * 2 * 3 + 12 / 2 / 2  = .计算表达式结果,并输出. 要求: 1.表达式运算符只有+.-.*./ ...

  10. 信息学奥赛一本通 1956:【11NOIP普及组】表达式的值 | 洛谷 P1310 [NOIP2011 普及组] 表达式的值

    [题目链接] ybt 1956:[11NOIP普及组]表达式的值 洛谷 P1310 [NOIP2011 普及组] 表达式的值 [题目考点] 表达式树 由带括号的中缀表达式构建表达式树 [解题思路] 思 ...

最新文章

  1. linux下安装boost
  2. « android通过xml配置实现的动画效果milestone的基本信息 » android...
  3. 为ubuntu添加多媒体以及flash等等常用包
  4. Bit-Z开放零门槛做市商计划 最高返100%交易手续费
  5. solver.prototxt参数说明(二)
  6. SQL 查询结果为 XML
  7. AWS成本估算的相关小工具
  8. c语言pow函数原型_c语言中pow函数的用法是什么?
  9. unity3D-下载安装指南
  10. 洛谷P2736 “破锣摇滚”乐队 Raucous Rockers
  11. 搭建Hadoop VM集群
  12. 应聘阿里的前车之鉴:从被回绝的系列原因出发,解读应聘阿里注意事项
  13. Java Mysql工具类封装
  14. 循环神经网络RNN——利用LSTM对脑电波信号进行分类,Keras实现
  15. 对视频文件进行简单的加密
  16. python grad_torch.autograd.grad()函数用法示例
  17. Linux服务篇之远程访问及控制SSH
  18. RSA加密算法讲解及C++实现
  19. 网卡mac地址的设置
  20. python终端命令执行提示找不到自定义模块

热门文章

  1. 如何使用PowerShell保护密码
  2. SQL Server 2016 SP1中的新功能和增强功能
  3. SQL Server FILESTREAM数据库损坏和修复
  4. sql数据库性能指标_SQL Server网络性能指标–最重要的指标
  5. 使用PowerShell SQL Server DBATools的IDENTITY列阈值
  6. 如何杀死远程服务器到本机的tcp连接
  7. [HNOI2009] 有趣的数列
  8. AtomicStampedReference
  9. 【C语言 基础】什么流程控制?
  10. PAT——乙级1036:跟奥巴马一起编程 乙级1027:打印沙漏 (有坑)