zoukankan      html  css  js  c++  java
  • 练手系列(3) 中缀表达式转后缀表达式

      最近在看数据结构和算法时,看到了中缀表达式和后缀表达式,感觉蛮有意思的,于是自己实现了一下,算是一种锻炼。

    首先,中缀表达式就是我们平时见惯了的算术式,比如:5+3这样的就是中缀表达式,而后缀表达式呢,就是53+这样的。因为转为后缀表达式后,算术式的计算会相对简单一些,可以用栈来实现。

    分析图如下:

    这种后缀表达式计算的最大的优点就是不用知道什么优先级。

    ②好,下面我们来看一下怎么从中缀表达式(5+3)变为后缀表达式(53+):

    好了,以上两张图片就是后缀表达式的相关分析。

    下面上具体代码:

      1 import java.util.Stack;
      2 
      3 public class Calculate {
      4     // 定义操作符号
      5     private static final char PLUS = '+';
      6     private static final char MINUS = '-';
      7     private static final char MULTIPLY = '*';
      8     private static final char DIVIDE = '/';
      9     private static final char LEFT_PARENTHESIS = '(';
     10     private static final char RIGHT_PARENTHESIS = ')';
     11 
     12     public static void main(String[] args) {
     13         String infix = "(3+(2-1))*5";
     14         String postfix = convert(infix);
     15         System.out.println(postfix);
     16         analysePostfix(postfix);
     17     }
     18 
     19     // 计算后缀表达式
     20     public static void analysePostfix(String postfix) {
     21         Stack<Double> stack = new Stack<Double>();
     22         char[] chs = postfix.toCharArray();
     23         for (int i = 0; i < chs.length; i++) {
     24             if (chs[i] != PLUS && chs[i] != MINUS && chs[i] != MULTIPLY
     25                     && chs[i] != DIVIDE) {
     26                 // 如果读取到的是数字,则加到栈中
     27                 stack.push(Double.valueOf(String.valueOf(chs[i])));
     28             } else {
     29                 // 如果读取到的是操作符,则从栈中弹出两个数字,并执行运算
     30                 double b = (double) stack.pop();
     31                 double a = (double) stack.pop();
     32                 char operator = chs[i];
     33                 double result = calculate(a, b, operator);
     34                 stack.push(result);
     35             }
     36         }
     37         System.out.println("result is : " + stack.pop());
     38     }
     39 
     40     public static double calculate(double a, double b, char operator) {
     41         switch (operator) {
     42         case PLUS:
     43             return a + b;
     44         case MINUS:
     45             return a - b;
     46         case MULTIPLY:
     47             return a * b;
     48         case DIVIDE:
     49             return a / b;
     50         }
     51         return 0;
     52     }
     53 
     54     // 中缀到后缀的转换
     55     public static String convert(String infix) {
     56         Stack<Character> vector = new Stack<Character>();
     57         char[] chs = infix.toCharArray();
     58         StringBuffer postfix = new StringBuffer();
     59         for (int i = 0; i < chs.length; i++) {
     60             // 如果是数字,直接插入表达式中
     61             if (chs[i] != PLUS && chs[i] != MINUS && chs[i] != MULTIPLY
     62                     && chs[i] != DIVIDE && chs[i] != LEFT_PARENTHESIS
     63                     && chs[i] != RIGHT_PARENTHESIS) {
     64                 postfix.append(String.valueOf(chs[i]));
     65             } else {
     66                 // 如果是左括号,直接压入栈中
     67                 if (LEFT_PARENTHESIS == chs[i]) {
     68                     vector.push(chs[i]);
     69                     continue;
     70                 }
     71                 // 如果是右括號,則去除棧裏面的左括號之上的所有操作符號
     72                 if (RIGHT_PARENTHESIS == chs[i]) {
     73                     while (LEFT_PARENTHESIS != vector.peek()) {
     74                         postfix.append(vector.pop());
     75                     }
     76                     vector.pop();
     77                 }
     78                 // 如果当前读到的操作符和栈里面的操作符一样,那么直接加到后缀表达式中
     79                 if (vector.size() > 0 && chs[i] == vector.peek()) {
     80                     postfix.append(String.valueOf(chs[i]));
     81                 } else if (vector.size() == 0 || chs[i] != vector.peek()) {
     82                     // 如果是乘号或者除号,直接压入栈中
     83                     if (MULTIPLY == chs[i] || DIVIDE == chs[i]) {
     84                         vector.push(chs[i]);
     85                     }
     86                     if (PLUS == chs[i] || MINUS == chs[i]) {
     87                         if (vector.size() > 0
     88                                 && (vector.peek() == MULTIPLY || vector.peek() == DIVIDE)) {
     89                             postfix.append(vector.pop().toString());
     90                             vector.push(chs[i]);
     91                         } else {
     92                             vector.push(chs[i]);
     93                         }
     94                     }
     95                 }
     96             }
     97             // 如果已经读完了中缀表达式,则弹出栈中所有操作符并加入到后缀表达式中
     98             if (i == chs.length - 1) {
     99                 for (int j = vector.size(); j > 0; j--) {
    100                     postfix.append(vector.pop().toString());
    101                 }
    102             }
    103         }
    104         return postfix.toString();
    105     }
    106 }
  • 相关阅读:
    Git
    vue
    vue
    echarts,dojo和兼容问题
    js数组对象以某一对象排序
    滚动条与图片移动
    vue
    vue
    vue页面组件化-父子组件传值
    phpquery笔记
  • 原文地址:https://www.cnblogs.com/huashui/p/3176608.html
Copyright © 2011-2022 走看看