_infix expression is a general expression method of arithmetic or logic formula, which conforms to the thinking of human routine calculation. The realization method of expression evaluation is a typical application of stack.
In computer, any expression is composed of operands, operators and boundaries. In this paper, we only discuss operations of integer, brackets, addition, subtraction, multiplication and division, remainder and square.
According to the four rules of operation:
(1) First in brackets, then out of brackets (2) Square first, multiply and divide the remainder, then add and subtract (3) Peer operations from left to right
For example: {5*3^2+[7+(5-2)]}*3. This example can be ignored first. Look at the following ideas first, and then come back to the example to do the experiment.
_Sets the priority of each operator according to the operation rules:
'+','-': 0 '*','/','%': 1 '^': 2 '[',']': -1 '(',')': -3 '{','}': -2
Computing process stack change table:
Serial number | Operator stack | Operator stack | Notes |
---|---|---|---|
0 | { | Encountering left parentheses directly into the stack | |
1 | 5 | { | Encountering operands directly into the stack |
2 | 5 | { * | Current high-priority stacking |
3 | 5 3 | { * | Operator |
4 | 5 3 | { * ^ | High priority stacking |
5 | 5 3 2 | { * ^ | / |
6 | 5 9 | { * | Current pointing symbol priority is small, do calculation |
6 | 45 | { + | Low priority, high computing/priority, stacking |
7 | 45 | { + [ | Left bracket stacking |
8 | 45 7 | { + [ | / |
9 | 45 7 | { + [ + | High priority stacking |
10 | 45 7 | { + [ + ( | Left bracket stacking |
11 | 45 7 5 | { + [ + ( | / |
12 | 45 7 5 | { + [ + ( - | High priority stacking |
13 | 45 7 5 2 | { + [ + ( - | / |
14 | 45 7 3 | { + [ + | Encounter right bracket calculation |
15 | 45 10 | { | Encounter right bracket calculation |
16 | 55 | Encounter right bracket calculation | |
17 | 55 | * | / |
18 | 55 3 | * | / |
19 | 165 |
The final result is 165.
Solutions:
index refers to where the expression string is currently traversed
- If it is left bracket, it goes directly into the symbol stack. This operation matches the right bracket for later traversal.
// If you enter the stack directly for the left parentheses if (isLeft(s.charAt(index))) { operS.push(s.charAt(index)); index++; }
- If the current pointing element is a number, consider whether it is a multi-digit number, so you need to keep looking backwards until you point to a symbol or to the last bit of the expression, then stop. Put the number into the operand stack.
// If the element is a number String number = ""; // This element is not a parenthesis, not an operator, but a number, which is considered in this article. while (!isOper(s.charAt(index)) && !isLeft(s.charAt(index)) && !isRight(s.charAt(index))) { number += s.charAt(index); // In order to prevent the number from reaching the last position of the expression, it is necessary to judge. Otherwise, it will go into a dead cycle. if (index == s.length() - 1) break; index++; } if (number != "") { numS.push(Integer.parseInt(number)); }
- If the current pointer is an operator, the following situations should be considered:
A. Current pointing operator priority <= symbol stack top symbol priority: need to pop up two numbers from the operand stack, symbol stack pop up a symbol, operation, operation resu lt s into the operand stack.
b. Current Pointing Operator Priority > Top Priority of Symbol Stack: Pressed directly into the Stack
c: Additional consideration 1: If the current point points to the last bit of the expression, and this one happens to be a number, and at this time, the symbol stack is not empty, and need to be calculated, so consider that when pointing to the last bit, you can also enter the discussion. After a calculation, the symbol stack is empty and exits.
d: Additional consideration 2: Since the input may accidentally input two or more operators in succession, after index ++, it is also necessary to consider whether this means an operator, and if so, the expression input is incorrect.
// If the element is an operator int num1, num2, oper, res; // When the formula reaches the last place, it has to be calculated once before it is finished. if (isOper(s.charAt(index)) || index == s.length() - 1) { // If the symbol stack is empty, the element goes directly to the stack while (!operS.isEmpty() && operS.priority(s.charAt(index)) <= operS.priority(operS.peek()) || !isOper(s.charAt(index))&&!isLeft(s.charAt(index)) && !isRight(s.charAt(index))) { if (operS.isEmpty()) break; num1 = numS.pop(); num2 = numS.pop(); oper = operS.pop(); res = campute(num1, num2, oper); numS.push(res); } // The last digit is the number to prevent him from entering the symbol stack, so a judgment is needed. if (isOper(s.charAt(index))) { operS.push(s.charAt(index)); index++; if (isOper(s.charAt(index))) { System.out.println("Continuous computational symbols, errors"); return 99999; } } }
- If the current point is to the right parentheses. At this time, the expression in parentheses should be calculated first, so the stack operation should be performed at this time. During the operation, the left parentheses stop operation. If the left parentheses encounter the same priority as the current right parentheses, then the matching of brackets is successful, the left parentheses are out of the stack, and index++ goes beyond the current right parentheses. Number, continue with the operation.
Additionally, considering the possible shortage of parentheses or mismatching, we first determine whether the symbol stack is empty when the right parentheses are used.
//If the element is in right parentheses if (isRight(s.charAt(index)) && !operS.isEmpty()) { while (!isLeft(operS.peek())) { num1 = numS.pop(); num2 = numS.pop(); oper = operS.pop(); res = campute(num1, num2, oper); numS.push(res); } if (operS.priority(s.charAt(index)) == operS.priority(operS.peek())) { operS.pop(); //The left bracket at the top of the pop-up stack index++; //Next bit crosses the current right bracket } else { System.out.println("Bracket matching error"); return 99999; } }
- true loop termination condition
// The calculation ends when the symbol stack is empty and the expression has reached the end. if (operS.isEmpty() && index == s.length() - 1) break;
- Result
// The last number left in the stack is the final result. return numS.pop();
Complete procedures, you can modify their own simpler
public class CamputeStackDemo { public static void main(String[] args) { String s = "{5^2%3^2+[7+(5+2)]*3}*2"; int i = doCamputee(s); System.out.println(i); } /** * subject * @param s Formula * @return Final results */ public static int doCamputee(String s) { int index = 0; // Index of strings // Create two stacks CamputeStack numS = new CamputeStack(50); // Digital stack CamputeStack operS = new CamputeStack(50); //Symbol stack while (true) { // If you enter the stack directly for the left parentheses if (isLeft(s.charAt(index))) { operS.push(s.charAt(index)); index++; } // If the element is a number String number = ""; while (!isOper(s.charAt(index)) && !isLeft(s.charAt(index)) && !isRight(s.charAt(index))) { number += s.charAt(index); if (index == s.length() - 1) break; index++; } if (number != "") { numS.push(Integer.parseInt(number)); } // If the element is a computational symbol int num1, num2, oper, res; // When the formula reaches the last place, it has to be calculated once before it is finished. if (isOper(s.charAt(index)) || index == s.length() - 1) { // If the symbol stack is empty, the element goes directly to the stack while (!operS.isEmpty() && operS.priority(s.charAt(index)) <= operS.priority(operS.peek()) || !isOper(s.charAt(index))) { if (operS.isEmpty()) break; num1 = numS.pop(); num2 = numS.pop(); oper = operS.pop(); res = campute(num1, num2, oper); numS.push(res); } // The last digit is the number to prevent him from entering the symbol stack, so a judgment is needed. if (isOper(s.charAt(index))) { operS.push(s.charAt(index)); index++; if (isOper(s.charAt(index))) { System.out.println("Continuous computational symbols, errors"); return 99999; } } } //If the element is in right parentheses if (isRight(s.charAt(index)) && !operS.isEmpty()) { while (!isLeft(operS.peek())) { num1 = numS.pop(); num2 = numS.pop(); oper = operS.pop(); res = campute(num1, num2, oper); numS.push(res); } if (operS.priority(s.charAt(index)) == operS.priority(operS.peek())) { operS.pop(); //The left bracket at the top of the pop-up stack index++; //Next bit crosses the current right bracket } else { System.out.println("Bracket matching error"); return 99999; } } // The calculation ends when the symbol stack is empty and the expression has reached the end. if (operS.isEmpty() && index == s.length() - 1) break; } // The last number left in the stack is the final result. return numS.pop(); } // Determine whether an element is a number or a symbol public static boolean isOper(char v) { if (v == '+' || v == '-' || v == '*' || v == '/' || v=='%' || v=='^') return true; return false; } // Judge whether it's left bracket public static boolean isLeft(int v) { if(v== '(' || v=='[' || v=='{') return true; return false; } // Judge whether it's a right bracket public static boolean isRight(int v) { if (v == ')' || v == ']' || v == '}') return true; return false; } // The result of calculating two numbers public static int campute(int num1, int num2, int oper) { int var = 0; switch (oper) { case '+': { var = num1 + num2; break; } case '-': { var = num2 - num1; break; } case '*': { var = num2 * num1; break; } case '/': { var = num2 / num1; break; } case '%':{ var = num2%num1; break; } case '^':{ var = 1; for(int i = 1 ; i <= num1 ; i++){ var *=num2; } break; } default: { System.out.println("The symbol is incorrect."); break; } } return var; } } // Establishment of stack class CamputeStack { private int maxSize; // Stack size private int[] stack; //Stack private int top = -1; //Define the top of the stack // Initialization stack public CamputeStack(int maxSize) { this.maxSize = maxSize; stack = new int[maxSize]; } // Determine whether the stack is empty public boolean isEmpty() { return top == -1; } // Determine whether the stack is full public boolean isFull() { return top == maxSize - 1; } // Push public void push(int v) { if (isFull()) { System.out.println("Stack full"); return; } top++; stack[top] = v; } // Stack out public int pop() { if (isEmpty()) { System.out.println("Stack space"); throw new RuntimeException("Stack space"); } int v = stack[top]; top--; return v; } // View stack top elements public int peek() { if (isEmpty()) { System.out.println("Stack space"); throw new RuntimeException("Stack space"); } return stack[top]; } // Returns the priority of the element public int priority(int oper) { int val = 100; switch (oper) { case '*': case '%': case '/': { val = 1; break; } case '^':{ val = 2; break; } case '+': case '-': { val = 0; break; } case '[': case ']': { val = -1; break; } case '{': case '}': { val = -2; break; } case '(': case ')': { val = -3; break; } } return val; } }
This is the end of this article. Everyone has a good life --- Bat!!!