简单的计算器实现(java)

包含 + - * / ( )优先级的表达式

用到了堆栈 、中缀表达式转后缀表达式的方法、类和对象的知识

  1 import java.util.Arrays;
  2 import java.util.Scanner;
  3 
  4 public class Compute{
  5     public static void main(String[] args){
  6         Scanner input = new Scanner(System.in);
  7         String str = input.nextLine();
  8         
  9         String[] inOrderArrays = strToArrays(str);
 10         System.out.println(Arrays.toString(inOrderArrays));
 11         String[] postOrderArrays = toPostOrder(inOrderArrays);
 12         System.out.println(Arrays.toString(inOrderArrays));
 13         Double result = toCompute(postOrderArrays);
 14         System.out.printf("%.3f",result);
 15     }
 16     /*
 17     将字符串分割成操作数和操作符的字符串数组
 18     */
 19     public  static String[] strToArrays(String str){
 20         int strLength = str.length();
 21         int beginIndex = 0; int endIndex = 0;
 22         String[] Arrays = new String[strLength];
 23         int arraysIndex = 0;
 24 
 25         for(int i = 0; i < strLength; i++){
 26             if(str.charAt(i)=='*'||str.charAt(i)=='/'||str.charAt(i)=='+'||str.charAt(i)=='-'||str.charAt(i)=='('||str.charAt(i)==')'){
 27                 endIndex = i -1 ;
 28                 if(beginIndex <= endIndex ){
 29                     Arrays[arraysIndex] = str.substring(beginIndex, endIndex+1);
 30                     Arrays[arraysIndex + 1] = String.valueOf(str.charAt(i));
 31                     arraysIndex += 2;
 32                     beginIndex = i + 1;
 33                 }
 34                 else{
 35                     Arrays[arraysIndex] = String.valueOf(str.charAt(i));
 36                     arraysIndex += 1;
 37                     beginIndex = i + 1;
 38                 }
 39             }
 40         }
 41         Arrays[arraysIndex] = str.substring(beginIndex, str.length());
 42         String[] Arrays2 = new String[arraysIndex+1];
 43         for(int i = 0; i < arraysIndex+1; i++) {
 44             Arrays2[i] = Arrays[i];
 45         }
 46         return Arrays2;
 47     }
 48     /*
 49     将中缀表达式转为后缀表达式,返回的是字符串数组
 50     */
 51     public static String[] toPostOrder(String[] arrays){  
 52         /*规则:   
 53         *1,运算数直接输出
 54         *2,左括号压入堆栈
 55         *3,右括号 将栈顶的运算符弹出并输出,括号出栈不输出
 56         *4,运算符:
 57         *    若优先级大于栈顶运算符,压入栈
 58         *    若优先级小于或等于栈顶运算符,栈顶运算符弹出并输出,
 59         *       继续和新栈顶比较,直到比栈顶运算符优先级大,将它压入栈
 60         *5,对象处理完毕后,将栈中运算符弹出并输出
 61         */
 62         Stack operStack = new Stack();//创建了一个操作符的栈
 63         int arraysLength = arrays.length;
 64         String[] arrays2 = new String[arraysLength];//输出后的字符数组
 65         int tempIndex = 0;
 66 
 67         //将字符串数组遍历
 68         for(int i = 0; i < arraysLength; i++){
 69             //操作符入栈
 70             if(isOper(arrays[i])){
 71                 //栈为空时直接入栈
 72                 if(operStack.isEmpty()){
 73                     operStack.push(arrays[i]);
 74                 }
 75                 else{
 76                     //操作符为"("时直接入栈
 77                     if( arrays[i].equals("(")  ){
 78                         operStack.push(arrays[i]);
 79                     }
 80                     //操作符为")"时栈顶出栈并输出,直到遇到"(", "("出栈,")"不入栈
 81                     else if( arrays[i].equals(")") ){
 82                         while(operStack.peek().equals("(") == false ){
 83                             arrays2[tempIndex] = operStack.pop();
 84                             tempIndex += 1;
 85                         }
 86                         operStack.pop();//"("出栈
 87                     }
 88                     //其他操作符需要比较与栈顶的优先级
 89                     else{
 90                         //栈顶是"(", 直接入栈
 91                         if(operStack.peek().equals("(") ){
 92                             operStack.push(arrays[i]);
 93                         }
 94                         else{
 95                             //优先级高,直接入栈
 96                             if(getPriority(arrays[i].charAt(0)) > getPriority(operStack.peek().charAt(0)) 
 97                                 && operStack.isEmpty() == false ){
 98                                 operStack.push(arrays[i]);
 99                             }
100                             //优先级低或者相等,栈顶出栈并输出,直到优先级比栈顶高
101                             else{
102                                 while(getPriority(arrays[i].charAt(0)) <= getPriority(operStack.peek().charAt(0))
103                                         && operStack.isEmpty() == false){
104                                     arrays2[tempIndex] = operStack.pop(); 
105                                     tempIndex += 1;
106                                     //若栈顶全部弹出,则直接入栈
107                                     if(operStack.isEmpty()) {
108                                         operStack.push(arrays[i]);
109                                         break;
110                                     }
111                                 }
112                                 if(getPriority(arrays[i].charAt(0)) > getPriority(operStack.peek().charAt(0))){
113                                     operStack.push(arrays[i]);
114                                 }
115                             }
116                         }
117                     }
118                 }
119             }
120             //操作数直接添加到 字符串数组2
121             else if(isNum(arrays[i])){
122                 arrays2[tempIndex] = arrays[i];
123                 tempIndex += 1;
124             }
125             else{
126             }
127         }
128         while(!operStack.isEmpty()){
129             arrays2[tempIndex] = operStack.pop();
130             tempIndex += 1;
131         }
132         String[] arrays3 = new String[tempIndex];
133         for(int i = 0; i < tempIndex ;i++){
134             arrays3[i] = arrays2[i];
135         }
136         return arrays3;
137     }
138     /*
139     得到操作符的优先级
140     */
141     public static int getPriority(char c){
142         if(c == '*' || c == '/'){
143             return 2;
144         }
145         else if (c == '+' || c == '-'){
146             return 1;
147         }
148         else{
149             return 999;
150         }
151     }
152     /*
153     由后缀表达式计算得值
154     */
155     public static double toCompute(String[] arrays){
156         /*规则:
157         *中缀表达式不用比较优先级
158         *将运算数入栈,每读到一个运算符
159         *就弹出栈顶的两个运算数,运算完毕后将结果压入栈
160         */
161         Stack numStack = new Stack();//创建了一个操作数的栈
162         int arraysLength = arrays.length;
163         //遍历后缀表达式的字符串数组
164         for(int i = 0; i < arraysLength; i++){
165             if(isNum(arrays[i])){
166                 numStack.push(arrays[i]);
167             }
168             else if(isOper(arrays[i])){
169                 Double num2 = Double.parseDouble(numStack.pop());
170                 Double num1 = Double.parseDouble(numStack.pop());
171                 if(arrays[i].equals("+")){
172                     Double result = num1 + num2;
173                     numStack.push(result.toString());
174                 }
175                 else if(arrays[i].equals("-")){
176                     Double result = num1 - num2;
177                     numStack.push(result.toString());
178                 }
179                 else if(arrays[i].equals("*")){
180                     Double result = num1 * num2;
181                     numStack.push(result.toString());
182                 }
183                 else if(arrays[i].equals("/")){
184                     Double result = num1 / num2;
185                     numStack.push(result.toString());
186                 }
187                 else{
188                 }
189             }
190             else{
191             }
192         }
193         Double result = Double.parseDouble(numStack.pop());
194         return result;
195     }
196     /*
197     判断该字符串是否为操作符
198     */
199     public static boolean isOper(String str){
200         if(str.equals("*")||str.equals("/")||
201             str.equals("+")||str.equals("-")||
202             str.equals("(")||str.equals(")")){
203                 return true;
204             }
205         else{
206             return false;
207         }
208     }
209     /*
210     判断该字符串是否为操作数
211     */
212     public static boolean isNum(String str){
213         if(str.equals("*")||str.equals("/")||
214             str.equals("+")||str.equals("-")||
215             str.equals("(")||str.equals(")")){
216                 return false;
217             }
218         else{
219             return true;
220         }
221     }
222 }

测试结果:

下一步,我在思考利用javaFX的界面编程知识实现这个简易计算器的界面化

 

猜你喜欢

转载自www.cnblogs.com/tangyihengloveleishunyue/p/10613757.html