簡單的計算器實現(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 }

設計一個存放字符串對象的棧類:

 1 import java.util.ArrayList;
 2 
 3 public class Stack{
 4     private ArrayList<String> stack = new ArrayList<>();
 5 
 6     public boolean isEmpty(){
 7         return stack.size() == 0;
 8     }
 9     public int getSize(){
10         return stack.size();
11     }
12     public String peek(){
13         if(!isEmpty()) {
14             return stack.get(stack.size() -1 );
15         }
16         else {
17             return "false";
18         }
19     }
20     public String pop(){
21         if(!isEmpty()){
22             String top = stack.get(stack.size() - 1);
23             stack.remove(stack.size() - 1);
24             return top;
25         }
26         else{
27             return "false";
28         }
29     }
30     public void push(String o){
31         stack.add(o);
32     }
33     @Override
34     public String toString(){
35         return "Stack:" + stack.toString();
36     }
37 }

 

測試結果:

下一步,我在思考利用javaFX的界面編程知識實現這個簡易計算器的界面化

 

 

 

修改:

在表達式的字符串轉換為字符串數組的函數中,沒有考慮到末尾可能是操作符結尾的情況,會導致字符串數組多了一個null元素

 

/*
    將字符串分割成操作數和操作符的字符串數組
    */
    public  static String[] strToArrays(String str){
        int strLength = str.length();
        int beginIndex = 0; int endIndex = 0;
        String[] Arrays = new String[strLength];
        int arraysIndex = 0;

        for(int i = 0; i < strLength; i++){
            if(str.charAt(i)=='*'||str.charAt(i)=='/'||str.charAt(i)=='+'||str.charAt(i)=='-'||str.charAt(i)=='('||str.charAt(i)==')'){
                endIndex = i -1 ;
                if(beginIndex <= endIndex ){
                    Arrays[arraysIndex] = str.substring(beginIndex, endIndex+1);
                    Arrays[arraysIndex + 1] = String.valueOf(str.charAt(i));
                    arraysIndex += 2;
                    beginIndex = i + 1;
                }
                else{
                    Arrays[arraysIndex] = String.valueOf(str.charAt(i));
                    arraysIndex += 1;
                    beginIndex = i + 1;
                }
            }
        }
//簡單的判斷一下表達式是否是以操作符結尾還是操作數結尾
if(!isOper(String.valueOf(str.charAt(strLength - 1)))){ Arrays[arraysIndex] = str.substring(beginIndex,strLength); arraysIndex += 1; } String[] Arrays2 = new String[arraysIndex]; for(int i = 0; i < arraysIndex; i++) { Arrays2[i] = Arrays[i]; } System.out.println(arraysIndex); return Arrays2; }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM