Introduction to prefix, infix and suffix expressions (implemented by computer code)

Posted by Youko on Tue, 15 Feb 2022 06:05:16 +0100

1. Prefix, infix, suffix expression

1.1 prefix expression (Polish expression)

  • Prefix expression is also called polish. The operator of prefix expression is before the operand,

  • Examples: (3 + 4) × The prefix expression corresponding to 5-6 is [- x+3456]

  • Computer evaluation of prefix expressions

    • Scan the expression from right to left. When encountering a number, push the number into the stack. When encountering an operator, pop up the two numbers at the top of the stack, use the operator to calculate them (top element and secondary top element), and put the result into the stack; Repeat the above process until the leftmost end of the expression, and the value obtained by the final operation is the result of the expression
    • For example: (3 + 4) × The prefix expression corresponding to 5-6 is- ×+ 3456. The evaluation steps for prefix expression are as follows:
      • Scan from right to left and push 6, 5, 4 and 3 onto the stack
      • Encounter the + operator, so pop up 3 and 4 (3 is the top element of the stack and 4 is the secondary top element), calculate the value of 3 + 4, get 7, and then put 7 on the stack
      • Next is × Operator, so pop up 7 and 5 and calculate 7 × 5 = 35, put 35 into the stack
      • Finally, the - Operator calculates the value of 35-6, i.e. 29, so as to obtain the final result

2.2 infix expression

  • Infix expression is a common operation expression, such as (3 + 4) × 5-6
  • The evaluation of infix expression is the most familiar to us, but it is not easy to operate for computer (we can see this problem in the previous case). Therefore, when calculating the result, infix expression is often transformed into other expressions for operation (generally into suffix expression.)

Suffix expression (2.3)

  • Suffix expression, also known as inverse Polish expression, is similar to prefix expression, except that the operator is after the operand

  • Examples: (3 + 4) × The suffix expression corresponding to 5-6 is 34 + 5 × 6-

  • Computer evaluation of suffix expression

    • Scan the expression from left to right. When encountering a number, push the number into the stack. When encountering an operator, pop up the two numbers at the top of the stack, use the operator to calculate them (secondary top element and top element), and put the result into the stack; Repeat the above process until the rightmost end of the expression, and the value obtained by the final operation is the result of the expression
    • For example: (3 + 4) × The suffix expression corresponding to 5-6 is 34 + 5 × 6 -, the evaluation steps for suffix expression are as follows:
      • Scan from left to right, pushing 3 and 4 onto the stack
      • Encounter the + operator, so pop up 4 and 3 (4 is the top element of the stack and 3 is the secondary top element), calculate the value of 3 + 4, get 7, and then put 7 on the stack
      • Stack 5
      • Next is × Operator, so pop up 5 and 7 and calculate 7 × 5 = 35, put 35 into the stack
      • Stack 6
      • Finally, the - Operator calculates the value of 35-6, i.e. 29, so as to obtain the final result

2. Inverse Polish calculator

  • It supports parentheses and multi digit integers. The calculator is simplified here. It only supports the addition, subtraction, multiplication and division of integers.

3.1 converting infix expression to suffix expression

  • Suffix expression is suitable for computer operation. However, it is not easy for people to write it, especially when the expression is very long. Therefore, in development, it is necessary to convert infix expression into suffix expression.

  • The specific steps are as follows:

    • 1. Initialize two stacks: operator stack s1 and stack s2 for storing intermediate results;
    • 2. Scan infix expression from left to right;
    • 3. When encountering an operand, press it to s2;
    • 4. When an operator is encountered, compare its priority with s1 stack top operator:
      • (1) If s1 is empty, or the stack top operator is an open bracket "("), this operator is directly put on the stack;
      • (2) Otherwise, if the priority is higher than that of the operator at the top of the stack, the operator is also pressed into s1;
      • (3) Otherwise, pop up the operator at the top of s1 stack and press it into s2, and go to (4-1) and the new top operation in s1 again
        Comparison of symbols;
    • 5. When parentheses are encountered:
      • (1) If it is an open bracket "(", press s1 directly
      • (2) If it is the closing parenthesis ")", the operators at the top of s1 stack will pop up in turn and press s2 until the left parenthesis is encountered. At this time, this pair of parentheses will be discarded
    • 6. Repeat steps 2 through 5 until the rightmost part of the expression
    • 7. Pop up the remaining operators in s1 and press them into s2
    • 8. Pop up the elements in s2 in turn and output them. The reverse order of the result is the suffix expression corresponding to the infix expression

3.2 computer evaluation of suffix expression

  • Scan the expression from left to right. When encountering a number, push the number into the stack. When encountering an operator, pop up the two numbers at the top of the stack, use the operator to calculate them (secondary top element and top element), and put the result into the stack; Repeat the above process until the rightmost end of the expression, and the value obtained by the final operation is the result of the expression
  • For example: (3 + 4) × The suffix expression corresponding to 5-6 is 34 + 5 × 6 -, the evaluation steps for suffix expression are as follows:
    • 1) Scan from left to right and press 3 and 4 into the stack;
    • 2) The value of the element pushed out of the stack is 3 + 7, so the value of the element pushed out of the stack is 3 + 7, and then calculated as 3 + 7;
    • 3) Put 5 into the stack;
    • 4) Next is × Operator, so pop up 5 and 7 and calculate 7 × 5 = 35, put 35 into the stack; 5) Put 6 into the stack;
    • 6) Finally, the - Operator calculates the value of 35-6, i.e. 29, so as to obtain the final result

3.3 reverse Polish computer_ code implementation

public class InfixToSuffix {
   public static void main(String[] args) {
       //(1) Complete the function of converting an infix expression into a suffix expression
       /*
       explain:
           1. 1+((2+3)*4)-5 => 1 2 3 + 4 * + 5 -
           2. Because it is inconvenient to operate str directly, first convert str to the List corresponding to infix expression
               That is, "1 + ((2 + 3) * 4) - 5" = > ArrayList [1, +, (, (, 2, +, 3,), *, 4,), -, 5]
           3.List corresponding to infix expression = > list corresponding to suffix expression
               That is, ArrayList [1, +, (, (, 2, +, 3,), *, 4,), -, 5] = > ArrayList [1,2,3, +, 4, *, +, 5, -]
        */
       String expression = "1+((2+3)*4)-5";

       List<String> infixExpressionList = toInfixExpressionList(expression);
       System.out.println("Infix expression List=" + infixExpressionList);//ArrayList [1,+,(,(,2,+,3,),*,4,),-,5]

       List<String> suffixExpressionList = parseSuffixExpressionList(infixExpressionList);
       System.out.println("Corresponding to suffix expression List=" + suffixExpressionList);//List corresponding to suffix expression = [1, 2, 3, +, 4, *, +, 5, -]
       
       //(2) Computer evaluation method for completing suffix expression
       int calculate = calculate(suffixExpressionList);
       System.out.printf("expression=%d", calculate);
   }

   //Method: convert infix expression str to corresponding List (str = = > List)
   //s=1+((2+3)x4)-5
   public static List<String> toInfixExpressionList(String s) {
       //Define a List to store the contents corresponding to infix expressions
       List<String> ls = new ArrayList<String>();
       int i = 0; //This is a pointer used to traverse the infix expression string
       String str; //Splicing of multi bit numbers
       char c; //Every time we traverse a character, we put it into c
       do {
           //If c is a non number, it needs to be added to ls
           if ((c = s.charAt(i)) < 48 || (c = s.charAt(i)) > 57) {
               ls.add("" + c);
               i++; //i need to move back
           } else { //If it is a number, multiple numbers need to be considered
               str = ""; //Set str to ''
               while (i < s.length() && (c = s.charAt(i)) >= 48 && (c = s.charAt(i)) <= 57) {
                   str += c; //Splicing
                   i++;
               }
               ls.add(str);
           }
       } while (i < s.length());
       return ls;
   }

   //Method: List corresponding to infix expression = > List corresponding to suffix expression
   //ArrayList [1,+,(,(,2,+,3,),*,4,),-,5] => Arraylist [1,2,3,+,4,*,+,5,-]
   public static List<String> parseSuffixExpressionList(List<String> ls) {
       //Define two stacks
       Stack<String> s1 = new Stack<String>(); //Symbol stack
       //Note: because s2 stack has no pop operation in the whole conversion process, and it needs to be output in reverse order, so it is troublesome
       //Instead of stack < string >, use list < string > S2 (sequential output)
       //Stack<String> s2 = new Stack<String>(); // Stack S2 for storing intermediate results
       List<String> s2 = new ArrayList<>(); //List s2 for storing intermediate results

       //Traversal ls
       for (String item : ls) {
           //If it's a number, add s2
           if (item.matches("\\d+")) {
               s2.add(item);
           } else if (item.equals("(")) {
               s1.push(item);
           } else if (item.equals(")")) {
               //If it is the closing parenthesis ")", the operators at the top of s1 stack will pop up in turn and press s2 until the left parenthesis is encountered. At this time, this pair of parentheses will be discarded
               //peek() view stack top elements
               while (!s1.peek().equals("(")) {
                   s2.add(s1.pop());
               }
               s1.pop(); //Pop (out of s1 stack and eliminate parentheses
           } else {
               //When the priority of item is less than or equal to s1 stack top operator, pop up the s1 stack top operator and add it to s2, and go to (4-1) again to compare with the new stack top operator in s1;
               while (s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(item)) {
                   s2.add(s1.pop());
               }
               //You also need to push the item into the stack
               s1.push(item);
           }
       }
       //Pop up the remaining operators in s1 and add s2
       while (s1.size() != 0) {
           s2.add(s1.pop());
       }

       return s2; //Note that because it is stored in the list, the output in order is the list corresponding to the corresponding suffix expression
   }

   //Complete the operation of the inverse Polish expression
   /*
       1.Scan from left to right to push 3 and 4 onto the stack
       2.Encounter the + operator, so pop up 4 and 3 (4 is the top element of the stack and 3 is the sub top element), calculate the value of 3 + 4, get 7, and then put 7 on the stack
       3.Stack 5
       4.Next is the X operator, so pop up 5 and 7, calculate 7x5=35, and put 35 on the stack
       5.Stack 6
       6.Finally, the - Operator calculates the value of 35-6, i.e. 29, so as to obtain the final result
    */
   public static int calculate(List<String> ls){
       //To create a stack, you only need one stack
       Stack<String> stack = new Stack<>();
       //Traversal ls
       for (String item : ls) {
           //Regular expressions are used here to extract numbers
           /*
               \d The matching character type is number + the number of matching characters is more than one
               \d Is to match a number, \ d + is to match one or more numbers, and the previous one \ is for escape
               \\d+(\\.\\d+)?Match decimal
            */
           if(item.matches("\\d+")){ //Number of matched bits
               //Push 
               stack.push(item);
           }else{
               //If it is an operator, pop out two number operations and put them on the stack
               int num2 = Integer.parseInt(stack.pop());
               int num1 = Integer.parseInt(stack.pop());
               int res = 0 ; //Store calculation results
               if(item.equals("+")){
                   res = num1 + num2;
               }else if(item.equals("-")){
                   res = num1 - num2; //Number ejected after - number ejected first
               }else if(item.equals("*")){
                   res = num1 * num2;
               }else if(item.equals("/")){
                   res = num1 / num2;
               }else {
                   throw new RuntimeException("Incorrect operator");
               }
               //Put res on the stack
               stack.push(res + "");
           }
       }
       //The last data left in the stack is the result of the operation
       return Integer.parseInt(stack.pop());
   }
}

//Writing a class Operation can return the priority corresponding to an operator
class Operation {
   private static int ADD = 1;
   private static int SUB = 1;
   private static int MUL = 2;
   private static int DIV = 2;

   //Write a method to return the priority number corresponding to the operator
   public static int getValue(String operation) {
       int result = 0;
       switch (operation) {
           case "+":
               result = ADD;
               break;
           case "-":
               result = SUB;
               break;
           case "*":
               result = MUL;
               break;
           case "/":
               result = DIV;
               break;
           default:
               System.out.println("The operator does not exist");
               break;
       }
       return result;
   }
}

 

Topics: Java data structure stack