博客
关于我
中缀表达式(算数表达式)转成前缀表达式(波兰表达式)并求计算值
阅读量:222 次
发布时间:2019-02-28

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

前缀表达式计算与中缀表达式转换

一、前缀表达式计算方法

前缀表达式(Prefix Expression)是一种无需括号的表达式形式,计算时从右到左扫描,数字直接入栈,运算符则弹出栈顶两个数进行计算。具体步骤如下:

  • 遇到数字时直接将其压入栈。
  • 遇到运算符时,弹出栈顶两个数,根据运算符对这两个数进行相应计算,并将结果再次入栈。
  • 重复上述过程直到表达式的最左端,最后栈中只剩下一个数,即为计算结果。
  • 二、中缀表达式转换为前缀表达式

    中缀表达式(Infix Expression)通常需要括号来明确运算优先级。将中缀表达式转换为前缀表达式的方法如下:

  • 初始化两个栈:运算符栈S1和结果栈S2。
  • 从右到左扫描表达式:
    • 遇到操作数,直接压入S2。
    • 遇到运算符:
      • 如果S1为空或栈顶运算符为右括号“)”,则将运算符压入S1。
      • 否则,若当前运算符优先级高于或等于S1栈顶运算符的优先级,则将S1栈顶运算符弹出并压入S2,重复步骤直到满足条件。
      • 最终将当前运算符压入S1。
  • 遇到括号:
    • 右括号“)”直接压入S1。
    • 左括号“(”则开始弹出S1栈顶的所有运算符并压入S2,直到遇到右括号“)”为止,右括号则丢弃。
  • 重复上述步骤直到扫描完整个表达式。
  • 将S1中剩余的运算符依次弹出并压入S2。
  • 最后依次弹出S2中的元素并输出,得到前缀表达式。
  • 三、代码实现

    package fighting;import java.util.Scanner;import java.util.Stack;import java.util.HashSet;public class Fighting {    private static HashSet
    oper = new HashSet<>(); private static void initOper() { oper.add('+'); oper.add('-'); oper.add('*'); oper.add('/'); } private static boolean isOper(char c) { return oper.contains(c); } private static boolean isNum(char c) { return c >= '0' && c <= '9'; } private static int priority(char c) { switch (c) { case '*': case '/': return 3; case '+': case '-': return 2; case ')': return 1; default: System.out.println("输入错误!"); return 0; } } public static int calculate(String str) { Stack
    numStack = new Stack<>(); char c; for (int i = str.length() - 1; i >= 0; i--) { if (isNum(c = str.charAt(i))) { numStack.push(c - '0'); } else { int num1 = numStack.pop(); int num2 = numStack.pop(); switch (c) { case '+': numStack.push(num1 + num2); break; case '-': numStack.push(num1 - num2); break; case '*': numStack.push(num1 * num2); break; case '/': if (num2 != 0) { numStack.push(num1 / num2); } else { throw new RuntimeException("除数不能为零!"); } break; } } } return numStack.pop(); } public static void main(String[] args) { initOper(); System.out.println("请输入表达式:"); Scanner sc = new Scanner(System.in()); String expression = sc.nextLine(); StringBuilder preExpression = new StringBuilder(); Stack
    operStack = new Stack<>(); for (int i = expression.length() - 1; i >= 0; i--) { char c = expression.charAt(i); if (isNum(c)) { preExpression.append(c); } else if (isOper(c)) { if (operStack.isEmpty()) { operStack.push(c); } else { while (true) { if (operStack.isEmpty() || priority(operStack.peek()) <= priority(c)) { break; } char pop = operStack.pop(); preExpression.append(pop); } operStack.push(c); } } else if (c == ')') { operStack.push(c); } else if (c == '(') { while ((pop = operStack.pop()) != ')') { preExpression.append(pop); } } else { System.out.println("输入表达式有误!"); } } while (!operStack.isEmpty()) { char pop = operStack.pop(); preExpression.append(pop); } preExpression = preExpression.reverse(); System.out.println("转换后的前缀表达式为:" + preExpression.toString()); System.out.println("前缀表达式计算的结果为:" + calculate(preExpression.toString())); }}

    运行结果

    转换后的前缀表达式为:( 3 1 + 2 * ) ( ( 5 3 - ) 4 / )

    计算结果:38

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

    你可能感兴趣的文章
    Mysql 数据类型一日期
    查看>>
    MySQL 数据类型和属性
    查看>>
    mysql 敲错命令 想取消怎么办?
    查看>>
    Mysql 整形列的字节与存储范围
    查看>>
    mysql 断电数据损坏,无法启动
    查看>>
    MySQL 日期时间类型的选择
    查看>>
    Mysql 时间操作(当天,昨天,7天,30天,半年,全年,季度)
    查看>>
    MySQL 是如何加锁的?
    查看>>
    MySQL 是怎样运行的 - InnoDB数据页结构
    查看>>
    mysql 更新子表_mysql 在update中实现子查询的方式
    查看>>
    MySQL 有什么优点?
    查看>>
    mysql 权限整理记录
    查看>>
    mysql 权限登录问题:ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)
    查看>>
    MYSQL 查看最大连接数和修改最大连接数
    查看>>
    MySQL 查看有哪些表
    查看>>
    mysql 查看锁_阿里/美团/字节面试官必问的Mysql锁机制,你真的明白吗
    查看>>
    MySql 查询以逗号分隔的字符串的方法(正则)
    查看>>
    MySQL 查询优化:提速查询效率的13大秘籍(避免使用SELECT 、分页查询的优化、合理使用连接、子查询的优化)(上)
    查看>>
    mysql 查询数据库所有表的字段信息
    查看>>
    【Java基础】什么是面向对象?
    查看>>