標籤:瞭解 並且 sign exti integer 運算式計算 練習 analysis 工作
2017-2018-2 1723 『Java程式設計』課程 結對程式設計練習-四則運算-準備階段
在一個人孤身奮鬥了將近半個學期以後,終於迎來的我們的第一次團隊協作共同編碼,也就是,我們的第一個結對程式設計練習——四則運算。顯然,他是考驗我們對於之前知識的掌握程度,而且考驗我們的能力,既然已經是一個結對程式設計練習,肯定存在著困難,但我們會迎難而上,一起解決問題,因為“團結就是力量!!!”
結對程式設計的戰友
20172316 趙乾宸:負責對於整數出題的編程;
20172319 唐才銘:負責對於分數出題的編程;
我:20172329 王文彬:負責對於計算和題目去重的編寫;
測試為分別進行測試,最後由趙乾宸進行集體測試。
每個人都是駕駛員,是彼此的引航員,團隊,分工明確是一部分,但是集體力量的結晶才是最偉大的!!!
看到題目的構思
1、計算的最開始構思:
首先,當第一次拿到這個題目的時候,首先進行思考的是加減乘除的整個運算邏輯,因為當時沒有瞭解過有尾碼標記法,所以一直在想如何用中綴運算式開始計算; 一方面,思考的是輸出的題目應該是字串類型還是資料類型,後來想了想,各有各自的優點和缺點,比如,計算的時候的確,數字是很方便的,但是當涉及到計算的時候,遇到的“+”、“-”、“*”、“/”,幾個符號就我現在的水平,沒有辦法去很好的解決,之後就想到了,假如將這幾個運算子號進行改變,將其變為幾個數字代表他們,不就可以了,最後有這樣一個問題,如果用“0”來代表“+”,有一個問題,因為“+”是一個字串,對其賦值還得進行強制轉化,對於程本身這樣其實是不利的,存在著一定的問題,所以,就先將計算問題放了放,開始想,如何出題;
2、開始出題:
最開始,還是以出題為主,考慮到“if-else”語句的複雜性,我們選擇了“swich語句“,因為,這樣可以進行人際互動,一方面可以實現我們所需要的輸入一個階數,可以完成對於該階數的出題;構思是這樣的,先利用對於符號的賦值,對於加減乘除四個符號進行對0123的賦值,以便於通過對於產生一個0~4(左閉右開)的一個隨機數取值實現對於字串的出題的隨機性,將輸出的符號給一個字元對象進行賦值,之後,開始在裡面加入數字,如何解決階數的控制,一方面,利用swich語句的方便,其次,利用了累加“+=”進行輸出,就會產生按照我們需求的題目;另一方面,需要輸出按照我們所敲入的數字進行題目個數的輸出,我們想到了運用數組和while語句,這樣,按照條件,輸出數組,就可以達到我們想要的一個結果,也就是一個理想的出題模型。
protected int a; protected String s1 = "", str = ""; public Compute2() { Scanner scan = new Scanner(System.in); System.out.println("幾級運算?"); int n = scan.nextInt(); Scanner qqq = new Scanner(System.in); System.out.println("產生幾個題目?"); int q = qqq.nextInt(); Object[] p = new Object[q] ; for (int index = 0; index < q; index++) { int a1 = (int) (Math.random() * 100); int a2 = (int) (Math.random() * 100); int t1 = (int) (Math.random() * 4); switch (t1) { case 0: { s1 = " + "; break; } case 1: { s1 = " - "; break; } case 2: { s1 = " * "; break; } case 3: { s1 = " / "; } } for (int i = 0; i < n - 1; i++) { int a = (int) (Math.random() * 100); int t = (int) (Math.random() * 4); String s = ""; switch (t) { case 0: { s = " + "; break; } case 1: { s = " - "; break; } case 2: { s = " * "; break; } case 3: { s = " / "; } } str += a + s; } str += a1 + s1 + a2; p[index]=str;
3、學習從中綴運算式到尾碼運算式的變化:
在課上,學習瞭解了尾碼運算式,這個運算式方便了我們進行計算代碼的編寫,利用了“棧”這個概念,在思考運算的過程中簡化了很多步驟;
在利用棧解決問題的時候有一個問題:就是假如是兩位元,如何去解決,這個問題在某一天的晚自習裡,學長給我們就這個問題進行了講解,利用StringTokenzer的方法進行對於字串的分隔,這個方法可以將兩個數字或者三個乃至三個以上的字元進行劃分,讓他們單獨成為整體,這樣就方便了我們的計算,就可以解決1234+不是123+4而是12+34的問題,感謝學長。
public String infixToSuffix() { Stack<Character> s = new Stack<Character>(); String suffix = ""; int length = str.length(); for (int i = 0; i < length; i++) { char temp;// 臨時字元變數 char ch = str.charAt(i); switch (ch) { case ' ': break; case '(': s.push(ch); break; case '+': case '-': while (s.size() != 0) { temp = s.pop(); if (temp == '(') { s.push('('); break; } suffix += temp; } s.push(ch); break; case '*': case '/': while (s.size() != 0) { temp = s.pop(); if (temp == '+' || temp == '-' || temp == '(') { s.push(temp); break; } else { suffix += temp; } } s.push(ch); break; case ')': while (!s.isEmpty()) { temp = s.pop(); if (temp == '(') { break; } else { suffix += temp; } } break; default: suffix += ch; break; } } while (s.size() != 0) { suffix += s.pop(); } return suffix;
4、在出題過程中去重問題上的思考:
如何去重,一方面,我們想到的是只要是結果相同的就是相同的,後來,發現並不是這樣簡單的,因為,在看了老師的部落格中所介紹的:
程式一次運行產生的題目不能重複,即任何兩道題目不能通過有限次交換+和×左右的算術運算式變換為同一道題目。例如,23 + 45 = 和45 + 23 = 是重複的題目,6 × 8 = 和8 × 6 = 也是重複的題目。3+(2+1)和1+2+3這兩個題目是重複的,由於+是左結合的,1+2+3等價於(1+2)+3,也就是3+(1+2),也就是3+(2+1)。但是1+2+3和3+2+1是不重複的兩道題,因為1+2+3等價於(1+2)+3,而3+2+1等價於(3+2)+1,它們之間不能通過有限次交換變成同一個題目。
看到了如此的要求,就開始進行思考;
5、計算問題:(我是負責這裡部分編寫的)
在遇見計算的時候,主要靠的就運用尾碼運算式的方法,利用棧進行計算,大概思路如下:
public Integer suffixToArithmetic() { Pattern pattern = Pattern.compile("\\d+||(\\d+\\.\\d+)"); String[] strings = str.split(""); Stack<Integer> stack = new Stack<Integer>(); for (int i = 0; i < strings.length; i++) { if (strings[i].equals("")) { continue; } if (pattern.matcher(strings[i]).matches()) { stack.push((int) Double.parseDouble(strings[i])); } else { double y = stack.pop(); double x = stack.pop(); stack.push((int) calculate(x, y, strings[i])); } } return stack.pop(); } private double calculate(double x, double y, String string) { if (string.trim().equals("+")) { return x + y; } if (string.trim().equals("-")) { return x - y; } if (string.trim().equals("*")) { return x * y; } if (string.trim().equals("/")) { return x / y; } return (double) 0; }
測試結果
轉尾碼:
遇到的一些問題
第一個問題:
如何去解決出題過程中如何去添加括弧,因為括弧的位置的不確定性就限制了我們如何去選擇,比如,假如出現像加法和乘法混在一起,括弧應該選擇加在加法位置?
解決方案:
我們想要將加法和括弧綁定在一起,之後利用swich語句判斷,什麼時候不需要在加法減法周圍加括弧,什麼時候不需要加。
第二個問題:
因為我們是先進行了代碼的編寫,然後通過對於代碼畫UML圖,所以現在就有以一個問題,因為一些代碼命名不同,使得存在一些問題,(這個是我們組的失誤,下次會糾正的)
解決方案:
現在正在匯總,之後打算統一為UML圖的編碼格式,然後對各自的代碼進行修改。
互評
20172316趙乾宸
小趙同學擔起了開始編寫代碼的大任,在發布任務的第二天,因為我和老唐同學在連續的兩天都有晚課,所以一開始,小趙同學的功勞功不可沒,而且他是我們團隊編程能力最強的,所以,我們都會向他看齊。
20172319唐才銘
老唐同學分配了我們的任務,並且也擔起了團隊的一遍大旗,為彼此加油鼓勁。
大家加油!!
UML圖
PSP
| PSP2.1 |
Personal Software Process Stages |
預估耗時(分鐘) |
實際耗時(分鐘) |
| Planning |
計劃 |
60 |
|
| Estimate |
估計這個任務需要多少時間 |
100 |
|
| Development |
開發 |
800 |
|
| Analysis |
需求分析 (包括學習新技術) |
100 |
|
| Coding Standard |
代碼規範 (為目前的開發制定合適的規範) |
30 |
|
| Design UML |
設計項目UML類圖 |
50 |
|
| Coding |
具體編碼 |
30 |
|
| Code Review |
代碼複審 |
50 |
|
| Test |
測試(自我測試,修改代碼,提交修改) |
30 |
|
| Size Measurement |
計算工作量(實際時間 |
30 |
|
| Postmortem & Process Improvement Plan |
事後總結, 並提出流程改善計劃 |
30 |
|
|
合計 |
1240 |
|
參考
Java堆棧的應用2----------中綴運算式轉為尾碼運算式的計算Java實現
用java實現複數的加減乘除運算
逆波蘭運算式
運算式計算 java 尾碼運算式
Java實現中綴運算式轉尾碼運算式並計算結果
2017-2018-2 1723 『Java程式設計』課程 結對程式設計練習-四則運算-準備階段