• 中缀表达式转换为后缀表达式


           在对表达式(中缀表达式)的运算求值的过程中,如果表达式比较复杂,那么对于计算机的内存和运算效率都有很大的浪费,而后缀表达式则没有此类困扰。理论上,后缀表达式可以计算任意复杂的计算式,并且其消耗的空间也只有少量的栈空间,栈中保存的只是转换过程中的运算符。本文则讲述了如何将中缀表达式转换为后缀表达式,实际代码如下:

    import java.util.Stack;
    
    public class MiddleToLast {
      public static String transfer(String str) {
        StringBuilder result = new StringBuilder("");
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < str.length(); i++) {  // 循环判断字符,这里默认输入的字符串是格式规整的表达式
          switch (str.charAt(i)) {
            case ' ':
              continue;
            case '+':
              result.append(plus(stack));
              break;
            case '-':
              result.append(sub(stack));
              break;
            case '*':
              result.append(mul(stack));
              break;
            case '/':
              result.append(div(stack));
              break;
            case '(':
              stack.push('(');
              break;
            case ')':
              result.append(parenthesis(stack));
              break;
            default:
              if (i > 0 && ('0' > str.charAt(i - 1) || str.charAt(i - 1) > '9')) {
                result.append(" ");
              }
              result.append(str.charAt(i));
          }
        }
        while (!stack.isEmpty()) {
          result.append(" " + stack.pop());
        }
        return result.toString();
      }
    
      // 反括号
      private static String parenthesis(Stack<Character> stack) {
        StringBuilder result = new StringBuilder("");
        while (!stack.isEmpty()) {
          if (stack.peek() == '(') {
            stack.pop();
            break;
          }
          result.append(" " + stack.pop());
        }
        return result.toString();
      }
    
      // 除号
      private static String div(Stack<Character> stack) {
        StringBuilder result = new StringBuilder("");
        while (!stack.isEmpty() && privilege(stack.peek(), '/')) {
          if (stack.peek() == '(') {
            break;
          }
          result.append(" " + stack.pop());
        }
        stack.push('/');
        return result.toString();
      }
    
      // 乘号
      private static String mul(Stack<Character> stack) {
        StringBuilder result = new StringBuilder("");
        while (!stack.isEmpty() && privilege(stack.peek(), '*')) {
          if (stack.peek() == '(') {
            break;
          }
          result.append(" " + stack.pop());
        }
        stack.push('*');
        return result.toString();
      }
    
      // 减号
      private static String sub(Stack<Character> stack) {
        StringBuilder result = new StringBuilder("");
        while (!stack.isEmpty() && privilege(stack.peek(), '-')) {
          if (stack.peek() == '(') {
            break;
          }
          result.append(" " + stack.pop());
        }
        stack.push('-');
        return result.toString();
      }
    
      // 加好
      private static String plus(Stack<Character> stack) {
        StringBuilder result = new StringBuilder("");
        while (!stack.isEmpty() && privilege(stack.peek(), '+')) {
          if (stack.peek() == '(') {
            break;
          }
          result.append(" " + stack.pop());
        }
        stack.push('+');
        return result.toString();
      }
    
      // 判断运算符优先级,若ch1大于ch2,则返回真
      private static boolean privilege(char ch1, char ch2) {
        if ((ch1 == '*' || ch1 == '/' || ch1 == '%') || ((ch1 == '+' || ch1 == '-') && (ch2 == '+' || ch2 == '-'))) {
          return true;
        }
        return false;
      }
    }

            在中缀表达式转换为后缀表达式的过程中,基本情况有三种:①操作数②操作符③括号。另外还需要考虑的一个问题是操作符的优先级。转换的思路为:当我们遇到操作数时,就将操作数(数字)直接输出,当我们遇到操作符时,就将操作符栈中顶部保存的操作符进行比较,如当前操作符优先级大于栈中操作符,那么就将当前操作压如栈中,如果当前操作符优先级低于栈中操作优先级,则将栈中顶部操作符弹出,并输出,继续比较栈中顶部操作符与当前操作符的优先级顺序,直至栈中没有操作符或栈中操作符的优先级低于当前操作符,再或者栈中操作符为顺括号"(",最后将当前操作符压入栈中。对于括号,如果遇到顺括号,则直接将顺括号放入栈中,继续扫描下一个字符,如果遇到反括号,则依次弹出栈中的操作符直至遇到顺括号为止。

  • 相关阅读:
    P2176 [USACO14FEB]路障Roadblock
    【最短路】Dijkstra+ 链式前向星+ 堆优化(优先队列)
    图论其一:图的存储
    【计算几何】二维凸包——Graham's Scan法
    P2742 【模板】二维凸包 / [USACO5.1]圈奶牛Fencing the Cows
    P2639 [USACO09OCT]Bessie的体重问题 【背包问题】
    如何评价代码质量的高低
    乔新亮-衡量企业 IT 团队价值的唯一指标是什么
    我总结了平台的5道坎
    hadoop namenode的工作机制
  • 原文地址:https://www.cnblogs.com/zhangxufeng/p/8284066.html
Copyright © 2020-2023  润新知