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

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

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

一、前缀表达式计算方法

前缀表达式(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/

    你可能感兴趣的文章
    mysqldump: Got error: 1044: Access denied for user ‘xx’@’xx’ to database ‘xx’ when using LOCK TABLES
    查看>>
    Mysqldump参数大全(参数来源于mysql5.5.19源码)
    查看>>
    mysqldump备份时忽略某些表
    查看>>
    mysqldump实现数据备份及灾难恢复
    查看>>
    mysqldump数据库备份无法进行操作只能查询 --single-transaction
    查看>>
    mysqldump的一些用法
    查看>>
    mysqli
    查看>>
    MySQLIntegrityConstraintViolationException异常处理
    查看>>
    mysqlreport分析工具详解
    查看>>
    MySQLSyntaxErrorException: Unknown error 1146和SQLSyntaxErrorException: Unknown error 1146
    查看>>
    Mysql_Postgresql中_geometry数据操作_st_astext_GeomFromEWKT函数_在java中转换geometry的16进制数据---PostgreSQL工作笔记007
    查看>>
    mysql_real_connect 参数注意
    查看>>
    mysql_secure_installation初始化数据库报Access denied
    查看>>
    MySQL_西安11月销售昨日未上架的产品_20161212
    查看>>
    Mysql——深入浅出InnoDB底层原理
    查看>>
    MySQL“被动”性能优化汇总
    查看>>
    MySQL、HBase 和 Elasticsearch:特点与区别详解
    查看>>
    MySQL、Redis高频面试题汇总
    查看>>
    MYSQL、SQL Server、Oracle数据库排序空值null问题及其解决办法
    查看>>
    mysql一个字段为空时使用另一个字段排序
    查看>>