博客
关于我
前缀、中缀、后缀表达式以及逆波兰计算器
阅读量:74 次
发布时间:2019-02-26

本文共 3222 字,大约阅读时间需要 10 分钟。

中缀表达式转换为逆波兰表达式的过程涉及几个关键步骤,包括初始化栈、扫描表达式、处理括号和运算符优先级。以下是详细的转换步骤:

  • 初始化栈:创建两个栈,一个用于存储运算符(运算符栈s1),另一个用于存储中间结果(操作数栈s2)。

  • 扫描表达式:从左到右遍历中缀表达式中的每个元素:

    • 数字:直接压入操作数栈s2。
    • 运算符
      • 比较运算符与运算符栈s1顶部的运算符优先级。
      • 如果当前运算符的优先级低于或等于s1顶部的运算符,弹出s1栈顶的运算符并压入s2,直到满足条件或遇到右括号。
      • 如果是左括号,直接压入运算符栈s1。
    • 右括号:弹出运算符栈s1,直到遇到左括号为止,并将弹出的运算符压入操作数栈s2,忽略左括号和右括号。
  • 处理剩余运算符:扫描完表达式后,弹出运算符栈s1中的运算符并压入操作数栈s2。

  • 逆波兰表达式:操作数栈s2中的元素按顺序即为逆波兰表达式。

  • 以下是具体的代码实现:

    package com.wang.stack;import java.util.ArrayList;import java.util.List;import java.util.Stack;public class PolandNotation {    public static void main(String[] args) {        String expression = "1+((2+3)*4)-5";        List
    infixList = toInfixExpressionList(expression); System.out.println(infixList); List
    suffixList = parseSuffixExpressionList(infixList); System.out.println("后缀表达式的List结果为:" + suffixList); int result = calculate(suffixList); System.out.println("计算结果为:" + result); } public static List
    toInfixExpressionList(String s) { List
    ls = new ArrayList<>(); int i = 0; String str = ""; char c; while (i < s.length()) { if ((c = s.charAt(i)) < 48 || (c = s.charAt(i)) > 57) { ls.add(c + ""); i++; } else { str = ""; while (i < s.length() && (c = s.charAt(i)) >= 48 && c <= 57) { str += c; i++; } if (!str.isEmpty()) { ls.add(str); } } } return ls; } public static List
    parseSuffixExpressionList(List
    ls) { Stack
    s1 = new Stack<>(); List
    s2 = new ArrayList<>(); for (String item : ls) { if (item.matches("\\d+")) { s2.add(item); } else if (item.equals("(")) { s1.push(item); } else if (item.equals(")")) { while (!s1.isEmpty() && !s1.peek().equals("(")) { s2.add(s1.pop()); } s1.pop(); } else { while (!s1.isEmpty() && getOperationPriority(s1.peek()) >= getOperationPriority(item)) { s2.add(s1.pop()); } s1.push(item); } } while (!s1.isEmpty()) { s2.add(s1.pop()); } return s2; } private static int getOperationPriority(String operation) { switch (operation) { case "+": case "-": return 1; case "*": case "/": return 2; default: return 0; } } public static int calculate(List
    ls) { Stack
    stack = new Stack<>(); for (String item : ls) { if (item.matches("\\d+")) { stack.push(item); } else { String num2 = stack.pop(); String num1 = stack.pop(); int res = 0; switch (item) { case "+": res = Integer.parseInt(num1) + Integer.parseInt(num2); break; case "-": res = Integer.parseInt(num1) - Integer.parseInt(num2); break; case "*": res = Integer.parseInt(num1) * Integer.parseInt(num2); break; case "/": res = Integer.parseInt(num1) / Integer.parseInt(num2); break; default: throw new RuntimeException("运算符有误"); } stack.push(res + ""); } } return Integer.parseInt(stack.pop()); } public static void main(String[] args) { // 请在此处添加您的测试代码 } // 其他辅助方法...}

    代码解释:

  • toInfixExpressionList:将中缀表达式转换为列表形式,处理多位数和括号。
  • parseSuffixExpressionList:将中缀表达式列表转换为逆波兰表达式列表,处理运算符优先级和括号。
  • calculate:使用栈计算逆波兰表达式,返回结果。
  • 该实现支持多位数和括号,确保正确处理运算符优先级,并能处理整数运算。可以扩展为支持浮点数运算和更多功能。

    转载地址:http://vhdk.baihongyu.com/

    你可能感兴趣的文章
    OpenResty(5):Openresty 模板渲染
    查看>>
    OpenSearch 使用二三事
    查看>>
    OpenSessionInView模式
    查看>>
    openshift搭建Istio企业级实战
    查看>>
    OpenSLL
    查看>>
    Openssh Openssl升级
    查看>>
    openssh 加固
    查看>>
    ViewPager切换滑动速度修改
    查看>>
    OpenSSL 引入了新的治理模式和项目,来增强社区参与和决策
    查看>>
    openssl内存分配,查看内存泄露
    查看>>
    OpenSSL创建SSL证书
    查看>>
    openssl在cygwin下编译错误:CPU不支持x86_64(CPU you selected does not support x86-64 instruction set )
    查看>>
    openssl安装
    查看>>
    openssl安装
    查看>>
    OpenSSL生成root CA及签发证书
    查看>>
    Openstack REST API
    查看>>
    OpenStack 上部署 Kubernetes 方案对比
    查看>>
    Openstack 之 网络设置静态IP地址
    查看>>
    OpenStack 存储服务详解
    查看>>
    openstack 导出镜像
    查看>>