//Use stack to calculate the result of an expression 10 * 9-3 + 5
- Calculation idea: there are two stacks, one for storing numbers and one for storing operators
- 1. Convert expression string to character array traverse character array
- 2. If the number is stored directly in the digital stack
- 3. If it is a symbol, it can be divided into two situations
(1) if the symbol stack is not empty, directly push the symbol into the stack.
(2) if the symbol stack is not empty
A. if the priority of the current operator is lower than or equal to the operator in the stack, two numbers need to be popped out of the data stack, and then a symbol needs to be popped out of the symbol stack for operation. The result will be pushed into the data stack, and then the current symbol will be pushed into the symbol stack.
b. if the priority of the current operator is higher than that of the operator in the stack, it will directly enter the symbol stack. - 4. When the expression is scanned, the corresponding number and symbol will be pop ped out from the number stack and symbol stack and run.
- 5. Only one number in the last stack is the result of the expression.
public class UseStack { public static void main(String[] args) { //test System.out.println(Calculate("10*9-3+5")); } public static int Calculate(String str) { ArrayStack2 numStack=new ArrayStack2(10);//Number stack ArrayStack2 operStack=new ArrayStack2(10);//Operator stack int index=0;//Subscript used to traverse a string int num1=0;//First number of pop ups int num2=0;//Second number of pop ups char oper=0;//Pop up operator int res=0;//Pop up operators and results char c=0;//Characters read from string char[] expression=str.toCharArray(); String keepnum=""; //Scan expression while(true) { c=expression[index]; //Judge what c is and deal with it accordingly if(operStack.isoper(c)) { //c is an operator if(!operStack.isEmpty()) { //There are two situations when the symbol stack is not empty //When operators are compared with operators in the stack, if the priority of current operators is lower than or equal to operators in the stack, two numbers need to be popped from the data stack, and then a symbol needs to be popped from the symbol stack for operation. if(operStack.priority(c)<=operStack.priority((char) operStack.peek())){ num1=numStack.pop(); num2=numStack.pop(); oper=(char) operStack.pop(); res=numStack.calculate(num1, num2, oper); numStack.push(res); //Remember to store the traversal operators in the symbol stack after the operation operStack.push(c); }else {//If the priority of the current operator is higher than the one in the stack, it will be directly put into the symbol stack. operStack.push(c); } }else { //If the symbol stack is empty, put the symbol directly into the stack. operStack.push(c); } } else { //If it's digital, it's directly in the digital stack. //Numstack.push (c-48); / / "1 + 3" -- the value of character 1 is 49 //Analytical thinking //1. When processing multi bit numbers, it is not allowed to immediately stack a number when it is found, because it may be multi bit. //2. When processing numbers, you need to express //If the number is the last number in expression, it will be directly put into the data stack. keepnum+=c; if(index==expression.length-1) { numStack.push(Integer.parseInt(keepnum)); } else { //If the next bit is an operator, push keepnum directly into the stack; if not, keep keepnum to continue traversing the next character if(operStack.isoper(expression[index+1])) { numStack.push(Integer.parseInt(keepnum)); //be careful!!! Remember to return keepnum to empty every time it runs out keepnum=""; } } } index++; if(index>=expression.length){ //Traversal end break; } } while(!operStack.isEmpty()) { //When all the symbols in the symbol stack pop up, the calculation ends completely. The first number in the data stack is the result of the operation. num1=numStack.pop(); num2=numStack.pop(); oper=(char) operStack.pop(); res=numStack.calculate(num1, num2, oper); //And store res in numStack numStack.push(res); } return res; } } //Array simulation stack class ArrayStack2 { private int maxsize; private int[] array; private int top=-1; public ArrayStack2(int maxsize) { this.maxsize=maxsize; //Notice passing maxsize into this.maxsize array=new int[this.maxsize]; } //Is stack full? public boolean isFull() { return top==maxsize-1; } //Is stack empty? public boolean isEmpty() { return top==-1; } //Stack operation public void push(int value) { //Judge whether the stack is full if(top==maxsize-1) { System.out.println("The stack is full."); }else { top++; array[top]=value; } } //Stack operation public int pop() { //Judge whether the stack is empty if(top==-1) { throw new RuntimeException("Stack empty, no data"); }else { int value=array[top]; top--; return value; } } //Pop up top element public int peek() { return array[top]; } //Traverse the stack from top to bottom public void read() { if(top!=-1) { for(int i=top;i>=0;i--) { System.out.println(i+"---"+array[i]); } } } //The priority priority of the return operator is represented by a number set by the programmer. //The higher the number, the higher the priority public int priority(char oper) { if(oper=='*'||oper=='/') { return 1; } if(oper=='+'||oper=='-') { return 0; }else { return -1; } } //Judge whether it is an operator public boolean isoper(char c) { if(c=='+'||c=='-'||c=='*'||c=='/') { return true; }else return false; } //Calculation public int calculate(int num1,int num2,char oper) { int res=0; switch(oper) { case '+': res=num1+num2; break; case '-': res=num2-num1; break; case '*': res=num2*num1; break; case '/': res=num2 / num1; break; default: break; } return res; } }