1. 程式人生 > >20175325 第一周結對編程項目 四則運算

20175325 第一周結對編程項目 四則運算

設計文檔 comm calc htm Coding 運算符和 解決方法 指針函數 ack

20175325 第一周結對編程項目 四則運算

一、需求分析:

  • 能根據用戶輸入的數字生成四則運算的題目數量
  • 能自動生成規定範圍內的四則運算題目(加、減、乘、除)
  • 能夠判斷四則運算的結果是否正確並進行數量統計
  • 能多次生成四則運算題目
  • 支持多運算符
  • 用戶能夠選擇是否開始答題
  • 統計題目正確率
  • 題目去重
  • 多語言支持:簡體中文, 繁體中文, English
  • 文件:
  • 處理生成題目並輸出到文件
  • 完成題目後從文件讀入並判題

二、設計思路:

  1. 和之前所學的C語言中的四則運算方法作類比,在JAVA中運用了C語言裏的一些思維。
  2. 產生隨機數並且考慮符號的優先級。
  3. 為了計算方便,把整數作為分數計算。
  4. 根據輸入的兩個參數決定表達式的數量及四則運算的範圍,隨機生成其範圍內的自然數及運算符。
  5. 能隨機插入左括號並在相應的位置插入右括號。
  6. 根據四則運算規律進行四則運算,能判斷結果是否正確,並輸出正確率。
    三、UML類圖:

技術分享圖片

四、結果測試:

技術分享圖片
技術分享圖片
技術分享圖片

五、碼雲鏈接:
碼雲鏈接:https://gitee.com/sgm5/text1/commit/fc8bcd8eb49331286e7d1a31d93c3de07b329154
六、實現過程中的關鍵代碼解釋:

  • 法則:

1.如果遇到數字,我們就直接將其輸出。
2.如果遇到非數字時,若棧為空或者該符號為左括號或者棧頂元素為括號,直接入棧。
3.如果遇到一個右括號,持續出棧並輸出符號,直到棧頂元素為左括號,然後將左括號出棧(註意,左括號只出棧,不輸出),右括號不入棧。

4.如果遇到運算符號且棧非空,查看棧頂元素, 如果棧頂元素的運算優先級大於或者等於該運算符號,則持續出棧,直到棧頂元素優先級小於該運算符。最後將該元素入棧。
5.如果我們讀到了輸入的末尾,則將棧中所有元素依次彈出。

  • 關鍵代碼與註釋:
Random ran = new Random();隨機數方法創建對象
str += random.nextInt(B) % range_num + 1; 產生0-B範內圍隨機數
String signElement = sign[random.nextInt(5)];//產生隨機運算符號"+", "-", "x", "÷", "/" 
private Stack<String> numStack = null;// 數字棧:存儲表達式中的數字
private Stack<Character> charStack = null;// 符號棧:存儲表達式中的運算符和括號
//根據輸入的兩個參數決定表達式的數量及數值範圍,隨機生成數值範圍內的自然數及運算符,隨機插入左括號並在相應的位置插入右括號。
import java.util.ArrayList;
import java.util.Random;

public class Create {
    String[] sign = {"+", "-", "x", "÷", "/"};
    int range_num;
    Random random = new Random();

    
    public void setRange_num(int range_num) {
        this.range_num =range_num;
    }

    
    public String create() {
        String str = "";
        int local = random.nextInt(3);
        
        for (int j = 0; j < 3; j++) {
            if (local == 0 && j == 0) {
                str += "(";
            } else if (local == 2 && j == 1) {
                str += "(";
            }
            
            str += random.nextInt(range_num) % range_num + 1;   //產生指定範圍隨機數
            if (local == 0 && j == 1) {
                str += ")";
            }
            if (local == 2 && j == 2) {
                str += ")";
            }
            
            String signElement = sign[random.nextInt(5)];//產生隨機運算符號
            str += signElement;
            if (signElement == "/") {
                str += random.nextInt(range_num) % range_num + 1;
                signElement = sign[random.nextInt(5)];
                while (true) {
                    if (signElement != "/") {
                        str += signElement;
                        break;
                    }
                    signElement = sign[random.nextInt(5)];
                }
            }

        }
        str = str.substring(0, str.length() - 1);
        return str;
    }

    public void belongFraction(String strfraction) {
       //處理分數計算
           String[] fractionlist = null;
        if (strfraction.contains("+")) {
            fractionlist = strfraction.split("\\+");
            CalculateFraction(fractionlist, 0);
        } else if (strfraction.contains("-")) {
            fractionlist = strfraction.split("-");
            CalculateFraction(fractionlist, 1);
        } else if (strfraction.contains("x")) {
            fractionlist = strfraction.split("\\x");
            CalculateFraction(fractionlist, 2);
        } else if (strfraction.contains("÷")) {
            fractionlist = strfraction.split("÷");
            CalculateFraction(fractionlist, 3);
        }

    }

    public void CalculateFraction(String[] strlist, int flag) {
      //分數的四種基本運算
        String[] fraction1 = new String[2];
        String[] fraction2 = new String[2];
        
        if (strlist[0].contains("/"))
            fraction1 = strlist[0].split("/");
        else {
            fraction1[0] = strlist[0];
            fraction1[1] = "1";
        }
        if (strlist[1].contains("/"))
            fraction2 = strlist[1].split("/");
        else {
            fraction2[0] = strlist[1];
            fraction2[1] = "1";
        }

        Fraction fr1 = new Fraction(Integer.parseInt(fraction1[0]), Integer.parseInt(fraction1[1]));
        Fraction fr2 = new Fraction(Integer.parseInt(fraction2[0]), Integer.parseInt(fraction2[1]));
        fr1.print();
        
        switch (flag) {
            case 0:
                fr1.add(fr2).print();
                break;
            case 1:
                fr1.minus(fr2).print();
                break;
            case 2:
                fr1.multiply(fr2).print();
                break;
            case 3:
                fr1.divide(fr2).print();
                break;
        }
    }
}

七、遇到的問題與解決方法:
問題1:如圖所示:
技術分享圖片
解決方法:我們參考了一些博客(https://www.cnblogs.com/julinhuitianxia/p/6850493.html),添加了JAVA中一些常用的包,類似於C語言中庫的用法,使其可以直接調用類。

八、總結:

這次的題目是四則運算,剛看到題目時,由於之前學了的C語言,能有一個大概的思路,但是JAVA語言與C語言不太一樣,真正編寫代碼時,遇到了一些問題。在參考了老師的博客和從網上查找了一些資料以後,程序的編寫才稍微能進入正軌,但過程中遇到多次無法編譯和運行的情況,如:找不到一些類名和方法調用語句出錯,調用的指針函數為空的情況,我們也參考了一些博客:(https://www.cnblogs.com/julinhuitianxia/p/6850493.html)(https://www.cnblogs.com/fuck1/p/5995857.html)等, 幫助我們解決問題,通過這次結對作業,也加深了我對JAVA學習的印象,也彌補了之前學習中的一些不足。

對隊友的評價:
隊友是室友,兩個人的時間能相互調節,我們互相為對方的領航員和駕駛員,遇到困難和問題的時候,一起查資料,分析如何進行運算,在編寫程序時,兩個人剛開始並不知道如何著手,後來一起摸索學習,討論解決過程中所遇到的種種問題,也感受到了1+1>2的力量,遇到困難時能一起解決,一起編程,是學習上的夥伴,能互相監督。

九、結對照片:

技術分享圖片

十、PSP:

PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃 30 45
·Estimate · 估計這個任務需要多少時間 400 550
Development 開發 60 100
·Analysis ·需求分析 (包括學習新技術) 30 45
·Design Spec · 生成設計文檔 30 50
·Design Review ·設計復審 (和同事審核設計文檔) 45 80
·Coding Standard ·代碼規範 (為目前的開發制定合適的規範) 20 30
· Design · 具體設計 60 85
· Coding · 具體編碼 150 200
·Code Review ·代碼復審 20 45
·Test ·測試(自我測試,修改代碼,提交修改) 70 165
Reporting 報告 60 80
·Test Report · 測試報告 15 25
·Size Measurement ·計算工作量 20 15
·Postmortem &Process Improvement Plan · 事後總結, 並提出過程改進計劃 15 20
合計 1025 1535

20175325 第一周結對編程項目 四則運算