Java programming: infix expression to postfix expression

  • Postfix expressions are suitable for calculations, but they are not easy to write, especially when the expressions are very long. Therefore, in development, we need to convert infix expressions into postfix expressions.

  • Specific steps are as follows:

  1. Initialize two stacks: operator stack s1 and stack s2 for storing intermediate results;
  2. Scan the infix expression from left to right;
  3. When the operand is encountered, it is pressed to s2;
  4. When encountering an operator, compare its priority with the operator on the top of the s1 stack:
    1) If s1 is empty, or the operator on the top of the stack is a left parenthesis "(", then this operator is directly pushed onto the stack;
    2) Otherwise, If the priority is higher than that of the operator on the top of the stack, the operator is also pushed into s1;
    3) Otherwise, the operator on the top of the s1 stack is popped and pushed into s2, again to (4-1) and new in s1 The top of the stack operator is compared;
  5. When encountering parentheses:
    1) If it is a left parenthesis "(", then directly press s1
    2) If it is a right parenthesis ")", the operators at the top of the s1 stack will be popped up in turn, and s2 will be pressed until the left parenthesis is encountered So far, discard this pair of brackets at this time
  6. Repeat steps 2 to 5 until the rightmost of the expression
  7. Pop up the remaining operators in s1 and push them into s2
  8. Pop up the elements in s2 in turn and output, the reverse order of the result is the postfix expression corresponding to the infix expression
  • for example
    Insert picture description here
  • Code
  1. Thinking analysisInsert picture description here
  2. Code
    // 方法:将中缀表达式转成对应List
    public static List<String> toInFixExpressionList(String s) {
          
          
        // 定义一个List,存放中缀表达式对应的内容
        List<String> ls = new ArrayList<String>();
        int index = 0;   // 索引,用于遍历中缀表达式字符串
        String str = "";    // 对多位数的拼接工作
        char c = ' ';   // 每遍历到一个字符,就放入到c中
        do {
          
          
            // 如果c是一个非数组,就需要加入到ls中
            c = s.charAt(index);
            if (c < 48 || c > 57) {
          
           //非数字
                ls.add("" + c);
                index++;
            } else {
          
            // 如果是数字,需要考虑多位数拼接
                str = ""; // 先将str清空    '0'=>[48] '9'=>[57]
                while (index < s.length() && (c = s.charAt(index)) >= 48 && (c = s.charAt(index)) <= 57) {
          
          
                    str += c;
                    index++;
                }
                ls.add(str);
            }
        } while (index < s.length());
        return ls;
    }
    
    // 将得到的一个中缀表达式对应的List => 后缀表达式对应的List
    // 即:ArrayList[1,+,(,(,2,+,3,),*,4,),-,5] => ArrayList[1,2,3,+,4,*,+,5,-]
    public static List<String> parseSuffixExpressionList(List<String> ls) {
          
          
        // 定义两个栈
        Stack<String> s1 = new Stack<String>(); // 符号栈
        // 说明:因为s2这个栈,在整个转换过程中,没有pop操作,而且后面我们还需要逆序输出
        // 因此比较麻烦,这里我们就不用Stack<String> 直接使用List<String> s2 代替
        //Stack<String> s2 = new Stack<String>(); // 储存中间结果s2
        List<String> s2 = new ArrayList<String>();
        // 遍历ls
        for (String item : ls) {
          
          
            // 如果是一个数,就加入s2
            if (item.matches("\\d+")) {
          
          
                s2.add(item);
            } else if (item.equals("(")) {
          
          
                s1.push(item);
            } else if (item.equals(")")) {
          
          
                // 如果是右括号")",则依次弹出s1栈顶的运算符,并压入s2,知道遇到左括号为止,此时将这一对括号丢弃
                while (!s1.peek().equals("(")) {
          
          
                    s2.add(s1.pop());
                }
                s1.pop();   // 将"("小括号弹出s1栈,消除小括号
            } else {
          
          
                // 当item优先级小于等于s1栈顶运算符优先级,将s1栈顶的运算符弹出并加入s2,重复该工作
                // 问题:缺少一个比较优先级高度的方法
                while (s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(item)) {
          
          
                    s2.add(s1.pop());
                }
                // 还需要将item压入栈
                s1.push(item);
            }
        }
    
        // 将s1中剩余的运算符依次弹出并加入s2
        while (s1.size() != 0) {
          
          
            s2.add(s1.pop());
        }
    
        return s2; // 注意因为存放到List,因此按顺序输出就是对应的后缀表达式
    }
    

Guess you like

Origin blog.csdn.net/KaiSarH/article/details/108741023