首先我要說一下,我得作業我盡力了,但是能力有限,還需練習。
四則運算,改進程式碼流程:
1.手動輸入算式(屬於中綴表示式)
2.將中綴表示式轉化成字尾表示式 生成out陣列
3.一個運算元棧,一個運算子棧,按照字尾表示式計算方法將out中的字元分別放入兩個棧
4.當運算元棧只有一個數時結束計算。
程式碼分段解析如下:
中綴變字尾:
public List<String> SolveOrder(String[] in,HashMap<String,Integer>precedence){ //符合逆波蘭式(字尾)的輸出 List<String> out = new ArrayList<String>(); //操作符 Stack<String> ops= new Stack<String>(); for(int i=0;i<in.length;i++){ String s=in[i]; //碰見數值 就放進out陣列末尾 if(!precedence.containsKey(in[i])){ out.add(s); continue; } while(true){ //當儲存操作符的棧中“空”或“遇見左括號”或“棧頂的運算子優先順序 // 小於讀取字串當前字元的優先順序”時,符號入棧 if(ops.isEmpty()||s.equals("(")||(precedence.get(s) >precedence.get(ops.peek()))){ ops.push(s); break; } String op=ops.pop();//出棧得運算子 if(op.equals("(")){ break; }else{ out.add(op); } } } //若操作符棧不為空,就依次將剩餘的操作符放入out陣列 while(!ops.isEmpty()){ out.add(ops.pop()); } return out; }
根據字尾(逆波蘭式)計算。
public double calculateOut(String[] out) { //假設滿足逆波蘭式的輸出不為空卻長度不為零 assert (out != null && out.length != 0); //運算元棧 Stack<Double> stack = new Stack<Double>(); for (int i = 0; i < out.length; i++) { if (isNumber(out[i])) { stack.push(Double.parseDouble(out[i])); } else { double v1 = stack.pop(); double v2 = stack.pop(); double result = eval(out[i], v2, v1); stack.push(result); } } return stack.pop(); }
主函式:控制檯輸入完整算式。
public static void main(String[] args) { System.out.println("請輸入要計算的算式:"); Scanner sc= new Scanner(System.in); String inBefor = sc.nextLine(); String[] in=inBefor.split(""); Cal cc = new Cal(); HashMap<String, Integer> precedence=cc.priorityInfo();; cc.SolveOrder(in, precedence); System.out.println("所輸入的算式結果為:"+cc.calculateOut(in)); }
老師,這段程式碼我是看的別人部落格上寫的,只能說我看懂了,還沒到您要求的變成自己的,但是,老師 ,我實在寫不動了。。
關於結對程式設計,從上這門課是從無到有的認識。程式設計這種東西就像思想,兩個人share就是兩個人都有兩種。爭吵中才會進步。
1.最開始的爭論是關於用java還是c++?由於我倆未來可能想更多的使用java所以,最後決定用java。
2.關於複雜運算有兩種思想:對五個數字產生的四個運算子 進行討論,四個位置分別討論+—*/另一種就是使用堆疊進行計算,最後還是堆疊程式碼量比較小,選定!
3.關於數字與符號的儲存方式,一種是用類,一種是分為兩個陣列。用類,在處理陣列與字元的int String型別上不方便,最後決定用兩個陣列。
4.最後的程式碼加不加原來的兩個運算元的程式碼,最後沒加。
5.程式碼還有一點問題,發不發部落格?最後還是發了。。。
結語:我去睡覺了,現在已經5:27了