5.1封裝與測試

47黃傑發表於2015-04-30
原始碼:
/**
採用算符優先演算法計算表示式 * @param * String ex : 表示式的字串; * @return * String 型別的計算結果; * 運算子棧operatorList按優先順序存放運算子;運算數棧operandList存放運算數; */ public String evaluateExpression(String ex){ // 在表示式首尾加上字元'#'以方便比較運算子 StringBuffer exB = new StringBuffer(ex); exB.insert(0,'#'); exB.append('#'); ex = exB.toString(); StringBuffer operandBuffer = new StringBuffer(); // 運算數的字元緩衝區 java.util.LinkedList<BigDecimal> operandList = new LinkedList<BigDecimal>(); java.util.LinkedList<String> operatorList = new LinkedList<String>(); int count = 1; // 從ex的序號為1開始,即‘#’後 int num = 0 ; // 除錯用 operatorList.addLast("#"); while(count < ex.length()){ String ch = String.valueOf(ex.charAt(count)); if(Pattern.matches("[0-9//.]",ch) // 當前字元如果是數字或.就把它放到運算數緩衝區 ||(ch.equals("-") // "-"看成是負號的條件:在表示式的首位或在”(“之後; &&(count ==1 || ex.charAt(count-1) == '('))){ operandBuffer.append(ch); System.out.println(ch+"屬於運算數:"); // 除錯用 ++count; } else{ // 把運算數放入棧 if(Pattern.matches("[//+//-//*/////)//#]",ch) && operandBuffer.length() != 0){ operandList.addLast(new BigDecimal(Double.valueOf(operandBuffer.toString()).toString())); System.out.println("序號"+(++num)+":"+operandBuffer.toString()); // 除錯用 System.out.println(""); operandBuffer.delete(0,operandBuffer.length()); } System.out.println(ch+"屬於運算子:"); // 除錯用 System.out.println(""); // 比較運算子,並根據它進行計算 switch(compareOperator(operatorList.getLast(),ch)){ // ch優先順序高,將ch壓入運算子棧 case '<' : operatorList.addLast(ch); ++count; break; // 優先順序相等時,去掉()或前後的#; case '=' : operatorList.removeLast(); ++count; break; // ch優先順序低,從運算數棧取出兩個數,從運算子棧取出運算子,進行計算其結果放入運算數棧; case '>' : BigDecimal b = operandList.removeLast(); BigDecimal a = operandList.removeLast(); String curOperator = operatorList.removeLast(); try{ operandList.addLast(operate(a,curOperator,b)); }catch(ArithmeticException e){ return "除數不能為0!"; } break; // 運算子輸入錯誤的處理:終止計算,在螢幕顯示input error! default : return "輸入有誤!"; } } }//End 0f while for(BigDecimal e : operandList) // 除錯用 System.out.println(e.toString()); return operandList.getLast().toString(); } /** 比較前後運算子的優先順序 */ public char compareOperator(String operator1,String operator2){ char result = '/u0000'; // 區域性內部類的例項方法的區域性變數能自動初始化為'/u0000'嗎?不得行!!! char o1 = operator1.charAt(0); char o2 = operator2.charAt(0); switch(o1){ case '+': switch(o2){ case '+': result = '>'; break; case '-': result = '>'; break; case '*': result = '<'; break; case '/': result = '<'; break; case '(': result = '<'; break; case ')': result = '>'; break; case '#': result = '>'; break; } break; // 跳出case '+'; case '-': switch(o2){ case '+': result = '>'; break; case '-': result = '>'; break; case '*': result = '<'; break; case '/': result = '<'; break; case '(': result = '<'; break; case ')': result = '>'; break; case '#': result = '>'; break; } break; // 跳出case '-'; case '*': switch(o2){ case '+': result = '>'; break; case '-': result = '>'; break; case '*': result = '>'; break; case '/': result = '>'; break; case '(': result = '<'; break; case ')': result = '>'; break; case '#': result = '>'; break; } break; // 跳出case '*'; case '/': switch(o2){ case '+': result = '>'; break; case '-': result = '>'; break; case '*': result = '>'; break; case '/': result = '>'; break; case '(': result = '<'; break; case ')': result = '>'; break; case '#': result = '>'; break; } break; // 跳出case '/'; case '(': switch(o2){ case '+': result = '<'; break; case '-': result = '<'; break; case '*': result = '<'; break; case '/': result = '<'; break; case '(': result = '<'; break; case ')': result = '='; break; case '#': result = '?'; // (後不能是#,如果是則是錯誤輸入; break; } break; // 跳出case '('; case ')': switch(o2){ case '+': result = '>'; break; case '-': result = '>'; break; case '*': result = '>'; break; case '/': result = '>'; break; case '(': result = '?'; // )後不能接(; break; case ')': result = '>'; break; case '#': result = '>'; break; } break; // 跳出case ')'; case '#': switch(o2){ case '+': result = '<'; break; case '-': result = '<'; break; case '*': result = '<'; break; case '/': result = '<'; break; case '(': result = '<'; break; case ')': result = '?'; // #後不能接); break; case '#': result = '='; break; } break; // 跳出case '#'; }// End Of switch return result; } /** 根據運算子進行二元計算, * @param * BigDecimal型別 a ? b * @return: * BigDecimal型別的結果 */ public BigDecimal operate(BigDecimal a,String operator,BigDecimal b){ final int DEF_DIV_SCALE = 20; BigDecimal result = null; switch(operator.charAt(0)){ case '+': result = a.add(b); break; case '-': result = a.subtract(b); break; case '*': result = a.multiply(b); break; case '/': result = a.divide(b,DEF_DIV_SCALE,BigDecimal.ROUND_HALF_UP); break; } return result; }

 

相關文章