【算法与数据结构】栈--使用数组模拟栈实现计算器的四则运算(包含括号)

  1 public class Calculator{
  2     public static void main(String[] args){
  3         //String expression = "2+2*(3-1*2)-1";//3
  4         String expression = "2+1*(7+3)-(2+3*2)/2";
  5         ArraStack2 numStack = new ArraStack2(10);//数字栈
  6         ArraStack2 operStack = new ArraStack2(10);//符号栈
  7         ArraStack2 bracketStack = new ArraStack2(10);//括号栈
  8         int index = 0;//遍历索引
  9         int num1 = 0;
 10         int num2 = 0;
 11         int oper = 0;//运算符
 12         int res = 0;//运算结果
 13         int prio = 0;//括号标志位
 14         char ch = ' ';
 15         String keepNum = "";
 16         while (true) {
 17             ch = expression.substring(index, index + 1).charAt(0);//获取当前字符
 18             if (bracketStack.isBlacket(ch)) {//判断是否为括号
 19                 if (!bracketStack.isEmpty()) {
 20                     //括号栈不为空,意味着括号中的所有运算符都已添加到括号栈中                                   
 21                     prio = -2;//将优先级标志位置为-2,在接下来的代码中完成括号内的所有运算
 22                     //System.out.println("1");
 23                 } else {//括号栈为空,即遇到第一个括号
 24                     prio = bracketStack.priority(ch);//获取当前优先级作为标志位
 25                     //System.out.println("2");
 26                     index++;
 27                     continue;//遇到第一个括号时将index++然后继续while遍历,而不是跳出循环
 28                 }
 29             }
 30             if (operStack.isOper(ch)) {//判断是否为运算符
 31                 if (prio == 2) {//判断是否在括号内
 32                     if (!bracketStack.isEmpty()) {//判断括号栈是否为空,不为空时判断运算符的优先级
 33                         if (bracketStack.priority(ch) <= bracketStack.priority(bracketStack.peek())) {
 34                             num1 = numStack.pop();
 35                             num2 = numStack.pop();
 36                             oper = bracketStack.pop();
 37                             res = numStack.cal(num1, num2, oper);
 38                             numStack.push(res);
 39                             bracketStack.push(ch);
 40                             //System.out.println("3");
 41                         }else {//括号内当前操作符的优先级大于括号栈中的操作符,直接入括号栈
 42                             bracketStack.push(ch);
 43                         }
 44                     } else {//括号栈为空时直接将括号内的运算符添加到符号栈中
 45                         bracketStack.push(ch);
 46                     }
 47                 }else if(prio == -2) {//遇到第2个括号时完成括号内的所有运算
 48                     while (true){
 49                         if (bracketStack.isEmpty()){
 50                             prio = 0;//完成括号内运算后将prio重新置零,
 51                             break;
 52                         }
 53                         num1 = numStack.pop();
 54                         num2 = numStack.pop();
 55                         oper = bracketStack.pop();
 56                         res = numStack.cal(num1, num2, oper);
 57                         numStack.push(res);
 58                         //System.out.println("6");
 59                     }
 60                 } else {//不在括号内
 61                     //System.out.println("5");
 62                     if (!operStack.isEmpty()) {//符号栈不为空时判断两个运算符之间的优先级
 63                         if (operStack.priority(ch) <= operStack.priority(operStack.peek())) {
 64                             //当前优先级小于或者等于栈顶优先级时进行计算
 65                             num1 = numStack.pop();
 66                             num2 = numStack.pop();
 67                             oper = operStack.pop();
 68                             res = numStack.cal(num1, num2, oper);
 69                             numStack.push(res);
 70                             operStack.push(ch);
 71                             //System.out.println("4");
 72                         } else {//当前优先级较高时直接入符号栈
 73                             operStack.push(ch);
 74                         }
 75                     } else {//符号栈为空时直接入符号栈
 76                         operStack.push(ch);
 77                     }
 78                 }
 79             } else {
 80                 keepNum += ch;//进行多位数的保留
 81                 if (index == expression.length() - 1) {
 82                     numStack.push(Integer.parseInt(keepNum));//最后一位数直接入栈
 83                 } else {//当下一位是运算符时入数字栈,否则继续遍历
 84                     if (operStack.isOper(expression.substring(index + 1, index + 2).charAt(0))) {
 85                         numStack.push(Integer.parseInt(keepNum));
 86                         keepNum = "";//入栈后清空
 87                     }
 88                 }
 89             }
 90             index++;//向后遍历表达式
 91             if (index>=expression.length()){//当index大于或者等于表达式长度时遍历完毕
 92                 break;
 93             }
 94         }
 95         while (true){//遍历完整个表达式并且完成了部分优先级高的运算后完成剩下的运算
 96             if (operStack.isEmpty()){//符号栈为空时跳出循环
 97                 break;
 98             }
 99             num1 = numStack.pop();
100             num2 = numStack.pop();
101             oper = operStack.pop();
102             res = numStack.cal(num1,num2,oper);
103             numStack.push(res);
104         }
105         int res2 = numStack.pop();//数字栈中剩余的最后一个数字就是最终结果
106         System.out.printf("表达式 %s = %d\n",expression,res2);
107     }
108 }
109 
110 class ArraStack2{
111     private int maxSize;
112     private int[] stack;
113     private int top = -1;
114 
115     public ArraStack2(int maxSize){
116         this.maxSize = maxSize;
117         stack = new int[this.maxSize];
118     }
119     public int peek(){//查看栈顶数据
120         return stack[top];
121     }
122     public boolean isFull(){//栈满
123         return top == maxSize-1;
124     }
125     public boolean isEmpty(){//栈空
126         return top == -1;
127     }
128     public void push(int value){//入栈
129         if (isFull()){
130             System.out.println("栈满");
131             return;
132         }
133         top++;
134         stack[top] = value;
135     }
136     public int pop(){//出栈
137         if (isEmpty()){
138             throw new RuntimeException("栈空,没有数据");
139             //return 0;
140         }
141         int value = stack[top];
142         top--;
143         return value;
144     }
145     public void list(){//显示栈里的数据
146         if (isEmpty()){
147             System.out.println("栈空,没有数据~");
148             return;
149         }
150         for (int i = top;i>=0;i--){
151             System.out.printf("stack[%d]=%d",i,stack[i]);
152         }
153     }
154     public int priority(int oper){//运算优先级
155         if (oper == '(' || oper == ')'){
156             return 2;
157         }else if (oper == '*' || oper == '/'){
158             return 1;
159         }else if (oper == '+' || oper == '-'){
160             return 0;
161         }else {
162             return -1;
163         }
164     }
165     public boolean isOper(char val){//运算符也包括括号
166         return val == '(' || val == ')' || val == '+' || val == '-' || val == '*' || val == '/';
167     }
168     //判断是否为括号
169     public boolean isBlacket(char val){
170         return val == '(' || val == ')';
171     }
172     public int cal(int num1, int num2, int oper){
173         int res = 0;
174         switch (oper){
175             case '+':
176                 res = num1 + num2;
177                 break;
178             case '-':
179                 res = num2 - num1;
180                 break;
181             case '*':
182                 res = num1 * num2;
183                 break;
184             case '/':
185                 res = num2 / num1;
186                 break;
187             default:
188                 break;
189         }
190         return res;
191     }
192 }
运算结果如下:
表达式 2+1*(7+3)-(2+3*2)/2 = 8

 

posted @ 2020-05-25 16:45  DJames23  阅读(324)  评论(0编辑  收藏  举报