20172303 2017-2018-2 《程序設計與數據結構》結對編程項目-四則運算

20172303 2017-2018-2 《程序設計與數據結構》結對編程項目-四則運算

結對對象

  • 姓名:張昊然
  • 學號:20172322
  • 第一週博客地址:http://www.cnblogs.com/zhangyeye233/p/8977631.html
  • 擔任角色:
    • 前期:肯定類的個數和每一個類的基礎編寫
      • 領航員:範雯琪
      • 操做員:張昊然
      • 解釋:前期主要是我來肯定每一個類有什麼功能,裏面大概有什麼方法,張昊然負責先在IDEA裏把大致敲出來,當遇到有問題的地方,我來查而後他作其餘的。(其實前期主要是他乾的比較多,編寫每一個類都花了好久)
    • 中期:類的修改與優化(無明顯角色差異)
      • 解釋:在這個階段角色就不是很明顯了,兩我的把全部類平均分配分別找錯誤,誰找到了的話先本身解決,不能解決的話再一塊兒討論。
    • 後期:嘗試加入括號
      • 領航員:張昊然
      • 操做員:範雯琪
      • 解釋:這部分中綴轉後綴中加括號、產生題目時加括號的思路都是張昊然想的,而後我負責把他的思路用具體的代碼實現。

需求分析

  • 可自動生成題目,題目的難度和數量可由用戶本身定義
  • 題目支持整數、真分數和加減乘除四則運算
  • 可判斷用戶答案是否正確並輸出正確答案,最後計算用戶的正確率
  • 擴展需求:
    • 題目去重
    • 支持多種語言,語言類型可由用戶自行選擇
    • 可以使生成的題目及其正誤保存在一個記事本文件中

設計思路

1、產生隨機有理數php

  • 設計了一個運算數類,使其能夠隨機生成一個有理數,既能夠是整數也能夠是真分數。

2、生成題目html

  • 設計了一個生成題目類,先能夠隨機生成四種運算符,接着經過結合運算數和運算符生成題目。

3、計算題目java

  • 原本是想把真分數和整數的計算放在一塊兒,後經張旭升學長在課上提醒第四章的例題中已經提供了能夠進行分數運算的RationalNumber類
  • 設計了一個中綴轉後綴類,使用逆波蘭表示法
  • 設計了一個計算類,調用產生問題類和中綴轉後綴類,進行題目的計算。

4、測試類git

  • 設計一個測試類,並能實現讓用戶輸入題目難度和數量,判斷正誤並計算率。

5、UML圖
web

相關過程及解釋

  • 中綴轉後綴方法實現
import java.util.*;

public class InfixToSuffix
{
    private Stack<String> stack;
    private List<String> list;

    private String message, Message = "";


    public InfixToSuffix() {
        stack = new Stack<String>();   //  Store operator
        list = new ArrayList<String>();   //  Store operation number and operator
    }

    public void conversion(String expr) {
        String token;
        StringTokenizer tokenizer = new StringTokenizer(expr);

        while (tokenizer.hasMoreTokens()) {
            //  If tokenizer has the next value, loop and assign value.
            token = tokenizer.nextToken();

            if (token.equals("(")) {
                //  If the value of the token is the left parenthesis, then the stack
                stack.push(token);
            }else if (token.equals("+") || token.equals("-")) {
                //  If the value of token is "+" or "-", once again determine whether the stack is empty.
                if (!stack.empty()){
                    //  If the stack is not empty, judge what is the top element of the stack
                    if (stack.peek().equals("(")) {
                        //  If the top of the stack is "(", the operator enters the stack
                        stack.push(token);
                    }else{
                        //  Otherwise, remove the stack top elements first, add them to the list,
                        //  and then stack the operators into the stack.
                        list.add(stack.pop());
                        stack.push(token);
                    }
                }else {
                    //  Otherwise the operator enters the stack
                    stack.push(token);
                }
            }else if (token.equals("*") || token.equals("÷")){
                //  If the value of token is "*" or "÷", it again determines whether the stack is empty.
                if (!stack.empty()) {
                    //  If the stack is not empty, judge what is the top element of the stack
                    if (stack.peek().equals("*") || stack.peek().equals("÷")) {
                        //  If the top of the stack is "*" or "÷", remove the stack top elements first,
                        //  add them to the list, and then stack the operators into the stack.
                        list.add(stack.pop());
                        stack.push(token);
                    }else {
                        //  In addition, the operator directly enters the stack.
                        stack.push(token);
                    }
                }else {
                    //  If the stack is empty, the operator goes directly to the stack
                    stack.push(token);
                }
            } else if (token.equals(")")) {
                //  If encounter "), starts to circulate
                while (true) {
                    //  Remove the top element of the stack and assign it to A
                    String A = stack.pop();
                    if (!A.equals("(")) {
                        //  If A is not "(", it is added to the list
                        list.add(A);
                    } else {
                        //  If A is "(", exit the loop
                        break;
                    }
                }
            }else {
                //  If it is an arithmetic number, enter the list
                list.add(token);
            }
        }
        while (!stack.empty()) {
            //  Remove elements from the stack and add them to the list until the stack is empty.
            list.add(stack.pop());
        }
        ListIterator<String> li = list.listIterator();
        while (li.hasNext()) {
            Message += li.next() + " ";
            //  The elements in iterator are taken out in turn, and spaces are used as separators.
            li.remove();
        }
        message = Message;
    }

    public String getMessage() {
        return message;
    }
}
  • 這部分的關鍵點是StringTokenizer類,是張旭升學長在某個晚自習交給咱們的。
  • 它的具體方法有:

運行過程截圖

遇到的困難及解決方法

  • 問題一:在測試類中若是題目數量輸入「0」時仍會產生一道題,若是題目難度輸入「0」則會提示錯誤。
  • 解決方法:修改測試類,無論在哪一個位置輸入「0」時都會提示錯誤。
int j = 0;
            System.out.print("請輸入要生成的題目數:" );
            count = number.nextInt();
            while (count == 0)
            {
                System.out.println("錯誤,請輸入有效數字!(最小爲1,理論無上限)");
                System.out.print("請輸入要生成的題目數:");
                count = number.nextInt();
            }
            System.out.print("請輸入生成題目的級別(每增長一級多一個運算符,最低爲一級):");
            level = number.nextInt();
            while (level == 0)
            {
                System.out.println("錯誤,請輸入有效數字!(最小爲1,理論無上限)");
                System.out.print("請輸入生成題目的級別(每增長一級多一個運算符,最低爲一級):");
                level = number.nextInt();
            }
  • 問題2:在產生題目時會輸出多個相同的運算數和運算符
  • 解決方法:採用單步調試發現是有一步多加了一遍某個「運算數+運算符」
  • 問題3:在加了括號以後,產生的題目級別與實際級別不符(級別等於符號數)
  • 解決方法:修改了不少遍都沒有成功,詢問了於欣月同窗,但她們組制定級別的方式與咱們不一樣(她們將一級設爲加減,二級爲乘除,三級爲加減乘除)因此也沒能幫咱們解決問題,這個問題咱們會在接下來一週中儘快解決。

對結對的小夥伴作出評價

  • 張昊然在本次結對過程當中真的付出了不少,代碼的主體基本都是他完成的,原本咱們是兩人結對的不須要作括號,但在個人力排衆議之下他仍是贊成了,即使在還有第十章的內容沒有完成的狀況下。
  • 缺點是不會運用工具,代碼出錯時仍是本身一步步的看幹想,沒有想到使用DeBug功能_(:з」∠)_

團隊共同成果

  • 其實在前期和中期咱們基本上是各幹各的或者一我的幹完給另一我的,但在加括號這部分是集中討論最多的。
  • 在中綴轉後綴的時候爲了把括號加進去列了不少遍草稿幾乎把代碼從新寫了一遍。
  • 而在產生題目時,我原本的思路是把左括號和右括號也做爲運算符隨機產生,可是若是要實現左括號必定在右括號前面且括號以內至少有兩個運算數和運算符會很是麻煩。而張昊然就提出了另外一種思路就是當題目產生運算符以後設定一個隨機數來判斷是否加括號,實現上述功能就簡單了許多,在最後產生的題目能生成括號以後真的很是有成就感。
  • 可是咱們產生括號仍是存在不少問題,好比由於存在括號使得級別與實際不符,並且如今咱們的括號中只能放兩個運算數和運算符。因爲時間和我的能力問題咱們沒能在這周解決,但在下一週必定會把它完成的。

PSP

PSP2.1 Personal Software Process Stages 預估耗時(小時) 實際耗時(小時)
Planning 計劃 0.5 1.5
Estimate 估計這個任務須要多少時間 0.5 0.5
Development 開發 20 45
Analysis 需求分析 (包括學習新技術) 2 2
Coding Standard 代碼規範 (爲目前的開發制定合適的規範) 3 3.5
Design UML 設計項目UML類圖 1.5 2
Coding 具體編碼 10 20
Code Review 代碼複審 2 2
Test 測試(自我測試,修改代碼,提交修改) 2 2
Size Measurement 計算工做量(實際時間) 0.5 1
Postmortem & Process Improvement Plan 過後總結, 並提出過程改進計劃 1 1.5
合計 43 94

參考資料

相關文章
相關標籤/搜索