package creeper; import java.util.Scanner; public class size { private static int intercePosition = 0; // 記錄單個運算數據的長度 private static int[] intercePositionIndex = null; // 記錄「(」的下標 private static int[] intercePositionEnd = null; // 記錄「)」的下標 public static void main(String[] args) { Scanner input = new Scanner(System.in); do { System.out.println("請輸入你要計算的字符串(注意:只能輸入數字和加,減,乘除符號;輸入完畢後,請直接回車):"); String numberString = input.next().trim(); // 判斷輸入的運算字符串是否符合規定 if (ispassString(numberString) == false) { System.out.println("您輸入的計算字符串有誤,請正確輸入!"); } else { // 計算結果返回 System.out.println(interceResult(numberString)); } } while (true); } // 判斷是否有帶括號的運算字符串存在 private static String interceResult(String str) { String result = str; char[] numberString = str.toCharArray(); // 1+2+(1*2+1-1*2+5)+2+(1+5+9+10-11)+1*5/2+3 // 1+8-9+(1*8/2-5+(1+2+8))+4/5*8/3*2 int IndexStart = 0; // 記錄「(」的實際數量 int EndStart = 0; // 記錄「)」的實際數量 for (int i = 0; i < numberString.length; i++) { if ('(' == numberString[i]) { // 記錄最後一個正括號的位置 IndexStart = i; } if (')' == numberString[i]) { // 記錄反括號的最初始下標的位置 EndStart = i; // 截取最裏面一個括號裏的運算字符串 result = result.substring(IndexStart + 1, EndStart); // 截取括號的運算字符串進行運算,生成新的運算字符串 result = str.substring(0, IndexStart) + interceptOperation(result, '*', '/') + str.substring(EndStart + 1, str.length()); // 回調執行,其它小括號的運算字符串 return interceResult(result); } if (i == numberString.length - 1) if (EndStart == 0) break; } // 不存在括號了,再進行混合運算 result = interceptOperation(str, '*', '/'); return result; } // 不帶括號的四則運算 private static String interceptOperation(String operationNumber, char a, char b) { String mess = operationNumber; char[] stringOperation = mess.toCharArray(); // 循環遍歷運算字符串,並作相應的運算 for (int i = 0; i < stringOperation.length; i++) { // 判斷運算符所在的索引 if (stringOperation[i] == a || stringOperation[i] == b) { if (i != 0) { // 運算符前的第一個數 double num1 = interceptNumIndex(mess.substring(0, i)); // 記錄第一個數據的長度 int frontPosition = intercePosition; // 運算符前的第二個數 double num2 = interceptNumEnd(mess.substring(i + 1, stringOperation.length)); // 記錄第二個數據的長度 int backPosition = intercePosition; // 算完乘除,將結果替換到原來運算的位置,獲得新的運算字符串 String IndexMess = mess.substring(0, i - frontPosition + 1); String IndexResult = ""; // 判斷是否運算到最後的結果了 if (IndexMess.indexOf('+') == -1 && IndexMess.indexOf('*') == -1 && IndexMess.indexOf('/') == -1 && IndexMess.lastIndexOf('-') == -1) IndexMess = ""; if (IndexMess != "") IndexResult = IndexMess.lastIndexOf('-') == IndexMess .length() - 1 ? IndexMess.substring(0, i - frontPosition) : IndexMess; // 組裝新的運算字符串 mess = IndexResult// mess.substring(0,i-frontPosition+1) + reslutString("" + stringOperation[i], num1, num2) + mess.substring(i + backPosition + 1); // 0.111/1212/2/2/2/2/2/2/2 if (mess.lastIndexOf('-') == 0 && mess.indexOf('+') == -1 && mess.indexOf('*') == -1 && mess.indexOf('/') == -1) { break; } // 回調,繼續運算 return interceptOperation(mess, a, b);// 1+7-5+89/3+4-6*8/2+4-6 } else continue; } if (i == stringOperation.length - 1) { // 遞歸出口,判斷是否還有運算字符串在 if (mess.indexOf('+') != -1 || mess.indexOf('-') != -1) return interceptOperation(mess, '+', '-'); break; } } return mess; } // 截取第二個數 private static double interceptNumEnd(String str) { double a = 0; int InrerceIndex = 0; char[] stringOperation = str.toCharArray(); boolean ispas = false; // 記錄是否爲負數 for (int i = 0; i < stringOperation.length; i++) { switch (stringOperation[i]) { case '*': case '/': case '+': case '-': InrerceIndex = i; if (i != 0) // 判斷該數是否爲負數 ispas = true; break; default: break; } if (ispas) break; } // 判斷此數據是否在運算字符串的最後一位 if (InrerceIndex == 0) { a = Double.parseDouble(str); intercePosition = str.length(); if (ispas) intercePosition++; } else { a = Double.parseDouble(str.substring(0, InrerceIndex)); // 記錄數據的真實長度 intercePosition = str.substring(0, InrerceIndex).length(); } return a; } // 截取第一個數 private static double interceptNumIndex(String str) { double a = 0; // 記錄數據 int InrerceIndex = 0; // 記錄運算符的位置 boolean temp = false; // 記錄數據前運算符的狀態 char[] stringOperation = str.toCharArray(); for (int i = stringOperation.length - 1; i >= 0; i--) { switch (stringOperation[i]) { case '*': case '/': case '+': case '-': InrerceIndex = i; temp = true; break; default: break; } if (temp) break; } // 判斷此數據是否在運算字符串的第一位 if (InrerceIndex == 0) { a = Double.parseDouble(str); intercePosition = str.length(); // if(temp) // intercePosition++; } else { a = Double.parseDouble(str.substring(InrerceIndex, str.length())); // 記錄數據的真實長度 intercePosition = str.substring(InrerceIndex, str.length()) .length(); } return a; } // 計算結果 private static double reslutString(String operation, double num1, double num2) { double sumResult = 0; if (operation.equals("*")) sumResult = num1 * num2; if (operation.equals("-")) sumResult = num1 - num2; if (operation.equals("/")) sumResult = num1 / num2; if (operation.equals("+")) sumResult = num1 + num2; return sumResult; } // 判斷是否正確輸入運算方式 private static boolean ispassString(String messString) { boolean ispass = false; boolean operationIspass = true; // 記錄被除數的狀態 int ai = 0; // 記錄是否有運算符號的存在 char[] IsString = messString.toCharArray(); int num1 = 0; int num2 = 0; for (int i = 0; i < IsString.length; i++) { // 記錄有幾對小括號的存在 if ('(' == IsString[i]) num1++; if (')' == IsString[i]) num2++; // 判斷除數是否爲零 if ('/' == IsString[i] && IsString[i + 1] == '0') operationIspass = false; // 判斷是否輸入了運算符合 if (IsString[i] == '+' || IsString[i] == '-' || IsString[i] == '*' || IsString[i] == '/') ai++; if (i == IsString.length - 1) if (ai == 0) num2++; } if (operationIspass) if (num1 == num2) ispass = true; return ispass; } }
運行結果以下java
而後使用junit進行測試單元測試
測試代碼以下測試
package creeper; import static org.junit.Assert.*; import org.junit.Test; public class sizeTest { @Test public void testReslutString() { Double expectedAnswer = Double.valueOf(12); Double actualAnswer = Double.valueOf(2*6); assertEquals(expectedAnswer, actualAnswer); } }
結果以下spa
測試條爲綠色,說明測試結果與預期結果相同,程序沒有問題code
總結:blog
通過對JUnit 的瞭解,簡單對以前寫的計算器代碼作個測試,收穫頗豐:JUnit做爲最佳實踐測試任何可能的錯誤。單元測試不是用來證實是對的,而是爲了證實沒有錯。JUnit還有更強大的功能等着咱們去探索。遞歸