1. Infix expression = > infix expression List
give an example:
- Infix expression: 1 + ((2 + 3) × 4)-5
- List corresponding to infix expression = [1, +, (, (, 2, +, 3,), *, 4,), -, 5]
Code implementation:
// s="1+((2+3)×4)-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 a character is traversed, it is put into c do { //If c is a non number, add 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 = ""; //First set str to "" '0' [48] - [9 '[57] 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;//return }
Note:
- Extract characters from String (s.charAt(i))
- Judge whether it is a number (48 < = x < = 57) ['0' - > '9']
- Method for judging whether a character is a multi bit number (while)
2. Infix expression List = > suffix expression List
give an example:
ArrayList [1,+,(,(,2,+,3,),,4,),-,5] => ArrayList [1,2,3,+,4,,+,5,–]
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 operator at the top of the stack is an open parenthesis "(", this operator will be directly put on the stack;
- The priority is higher than that of the stack top operator, and the operator is also pushed into s1
- Otherwise, pop up the operator at the top of the stack in s1 and press it into s2. Go to (4-1) again and compare it with the new operator at the top of the stack in s1
-
5: When parentheses are encountered:
- If it is the left parenthesis "(", press s1 directly
- 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
Code example:
//That is, ArrayList [1,+,(,(,2,+,3,),*,4,),-,5] = "ArrayList [1,2,3,+,4,*,+,5, –] //Method: List corresponding to infix expression = > List corresponding to suffix expression public static List<String> parseSuffixExpreesionList(List<String> ls) { //Define two stacks Stack<String> s1 = new Stack<String>(); // Symbol stack //Note: because s2 is a stack, there is no pop operation in the whole conversion process, and we need to output it in reverse order later //Therefore, it's troublesome. Here, we don't need stack < string > to directly use list < string > S2 //Stack<String> s2 = new Stack<String>(); // Stack S2 for storing intermediate results List<String> s2 = new ArrayList<String>(); // Lists2 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 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 the top operator of s1 stack, pop up the top operator of s1 stack and add it to s2. Go to (4.1) again and compare it with the new top operator in s1 //Problem: we lack a way to compare priorities while(s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(item) ) { s2.add(s1.pop()); } //You also need to push the item onto 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 }
Note:
- Definition of stack (Stack s1 = new Stack())
- Add push() to the stack
- peek() pop stack
- Regular expression: judge whether it is a number (item.matches("\ \ d +")
3. Operation of inverse Polish expression
//Complete the operation of the inverse Polish expression /* * 1)Scan from left to right and press 3 and 4 into the stack; 2)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; 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 */ public static int calculate(List<String> ls) { // To create a stack, you only need one stack Stack<String> stack = new Stack<String>(); // Traversal ls for (String item : ls) { // Regular expressions are used here to extract numbers if (item.matches("\\d+")) { // The number of multiple bits matches // Push stack.push(item); } else { // pop out two numbers, operate them, and then put them on the stack int num2 = Integer.parseInt(stack.pop()); int num1 = Integer.parseInt(stack.pop()); int res = 0; if (item.equals("+")) { res = num1 + num2; } else if (item.equals("-")) { res = num1 - num2; } 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()); } }
4. Others
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 corresponding priority number 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" + operation); break; } return result; } }
Complete the function of converting an infix expression into a suffix expression
//Complete the function of converting an infix expression into a suffix expression /*explain //1. 1+((2+3)×4)-5 => Turn to 1 2 3 + 4 × + 5 – //2. Because it is inconvenient to operate str directly, first set "1 + ((2 + 3) × 4) - 5 "=" List corresponding to the expression of infix // I.e. "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";//Note the expression List<String> infixExpressionList = toInfixExpressionList(expression); System.out.println("Infix expression List=" + infixExpressionList); // ArrayList [1,+,(,(,2,+,3,),*,4,),-,5] List<String> suffixExpreesionList = parseSuffixExpreesionList(infixExpressionList); System.out.println("Corresponding to suffix expression List" + suffixExpreesionList); //ArrayList [1,2,3,+,4,*,+,5,–] System.out.printf("expression=%d", calculate(suffixExpreesionList)); // ?
Full code:
package com.atguigu.stack; import java.util.ArrayList; import java.util.List; import java.util.Stack; public class PolandNotation { public static void main(String[] args) { //Complete the function of converting an infix expression into a suffix expression /*explain //1. 1+((2+3)×4)-5 => Turn to 1 2 3 + 4 × + 5 – //2. Because it is inconvenient to operate str directly, first set "1 + ((2 + 3) × 4) - 5 "=" List corresponding to the expression of infix // I.e. "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";//Note the expression List<String> infixExpressionList = toInfixExpressionList(expression); System.out.println("Infix expression List=" + infixExpressionList); // ArrayList [1,+,(,(,2,+,3,),*,4,),-,5] List<String> suffixExpreesionList = parseSuffixExpreesionList(infixExpressionList); System.out.println("Corresponding to suffix expression List" + suffixExpreesionList); //ArrayList [1,2,3,+,4,*,+,5,–] System.out.printf("expression=%d", calculate(suffixExpreesionList)); // ? } //That is, ArrayList [1,+,(,(,2,+,3,),*,4,),-,5] = "ArrayList [1,2,3,+,4,*,+,5, –] //The suffix of the expression corresponding to List = > will be obtained public static List<String> parseSuffixExpreesionList(List<String> ls) { //Define two stacks Stack<String> s1 = new Stack<String>(); // Symbol stack //Note: because s2 is a stack, there is no pop operation in the whole conversion process, and we need to output it in reverse order later //Therefore, it's troublesome. Here, we don't need stack < string > to directly use list < string > S2 //Stack<String> s2 = new Stack<String>(); // Stack S2 for storing intermediate results List<String> s2 = new ArrayList<String>(); // Lists2 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 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 the top operator of s1 stack, pop up the top operator of s1 stack and add it to s2. Go to (4.1) again and compare it with the new top operator in s1 //Problem: we lack a way to compare priorities while(s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(item) ) { s2.add(s1.pop()); } //You also need to push the item onto 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 } // s="1+((2+3)×4)-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 a character is traversed, it is put into c do { //If c is a non number, I need to add 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 = ""; //First set str to "" '0' [48] - [9 '[57] 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;//return } //Complete the operation of the inverse Polish expression public static int calculate(List<String> ls) { // To create a stack, you only need one stack Stack<String> stack = new Stack<String>(); // Traversal ls for (String item : ls) { // Regular expressions are used here to extract numbers if (item.matches("\\d+")) { // The number of multiple bits matches // Push stack.push(item); } else { // pop out two numbers, operate them, and then put them on the stack int num2 = Integer.parseInt(stack.pop()); int num1 = Integer.parseInt(stack.pop()); int res = 0; if (item.equals("+")) { res = num1 + num2; } else if (item.equals("-")) { res = num1 - num2; } 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 corresponding priority number 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" + operation); break; } return result; } }
result