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