1. 程式人生 > >20165322 第二周結隊編程-四則運算

20165322 第二周結隊編程-四則運算

sta 進行 註意 學習方法 commond and 實驗 計算器 vid

結對編程-四則運算 整體總結

  • 學習筆記

  • 中綴表達式轉換為後綴表達式

    • 如果遇到數字,我們就直接將其輸出。
    • 如果遇到非數字時,若棧為空或者該符號為左括號或者棧頂元素為括號,直接入棧。
    • 如果遇到一個右括號,持續出棧並輸出符號,直到棧頂元素為左括號,然後將左括號出棧(註意,左括號只出棧,不輸出),右括號不入棧。
    • 如果遇到運算符號且棧非空,查看棧頂元素,如果棧頂元素的運算優先級大於或者等於該運算符號,則持續出棧,直到棧頂元素優先級小於該運算符。最後將該元素入棧。
    • 如果我們讀到了輸入的末尾,則將棧中所有元素依次彈出。
  • 生成隨機數的運用

    • Random ran = new Random();隨機數方法創建對象
    • int B = ran.nextInt(2);生成0—1之內的隨機數
  • 需求分析

    • 隨機生成題目
      • 生成題目數量根據用戶需求輸入
      • 自動生成小學四則運算題目(加、減、乘、除)
      • 支持整數和真分數
      • 支持多運算符(比如生成包含100個運算符的題目)
    • 統計正確率
    • 能多次生成題目

    • 擴展需求
      • 題目去重
      • 支持多語言
      • 處理生成題目並輸出到文件
      • 完成題目後從文件讀入並判題
  • 設計思路

    • 實驗首先是完成一個計算器的功能,可以實現簡單的+、-、*、/運算
    • 實現多運算符,編入四個類分別實現整數運算、真分數運算、判斷結果正確並計算正確率
    • 利用JUnit檢測非法輸入
    • 設計一個主類生成隨機數,生成題目,並判斷正確率
    • 設計測試類,利用JUnit測試整數類與分數類的四則運算

uml圖:
技術分享圖片

實現真分數計算代碼及註釋

import java.util.Random;
public class Fraction {
    private int numerator, denominator;  //定義分母、分子

    public  Fraction (int numer, int denom)
    {

        if(denom == 0 )        //分子為0
            denom = 1;
        if (denom < 0)           //若分母小於0,則取分母為正值,分子為負值
        {
            numer = numer * -1;
            denom = denom * -1;
        }
        numerator = numer;
        denominator = denom;

        reduce();
    }

    public int getNumerator()
    {
        return numerator;
    }

    public int getDenominator()
    {
        return denominator;
    }


    public Fraction add(Fraction op2)          //實現真分數加法運算
    {
        int commonDenominator = denominator * op2.getDenominator();   //兩隨機數a1、a2的分母相乘,進行通分
        int numerator1 = numerator * op2.getDenominator();            //a1的分子=a1的分子與a2的分母相乘
        int numerator2 = op2.getNumerator() * denominator;           //a2的分子=a2的分子與a1的分母相乘
        int sum = numerator1 + numerator2;                            //將通分過後的兩個隨機數相加
        System.out.print("("+this.toString()+")" + " + " + "("+op2.toString()+")" + "=");
        return new Fraction (sum, commonDenominator);
    }

    public Fraction subtract(Fraction op2)           //實現真分數減法運算
    {
        int commonDenominator = denominator * op2.getDenominator();
        int numerator1 = numerator * op2.getDenominator();
        int numerator2 = op2.getNumerator() * denominator;
        int difference = numerator1 - numerator2;
        System.out.print("("+this.toString()+")" + " - " + "("+op2.toString()+")" + "=");
        return new Fraction(difference,commonDenominator);
    }

    public Fraction multiply (Fraction op2)              //實現真分數乘法運算
    {
        int numer = numerator * op2.getNumerator();
        int denom = denominator * op2.getDenominator();
        System.out.print("("+this.toString()+")" + " * " + "("+op2.toString()+")" + "=");
        return new Fraction (numer, denom);
    }

    public Fraction divide (Fraction op2)              //實現真分數除法運算
    {

        int numer = numerator * op2.getDenominator();
        int denom = denominator * op2.getNumerator();
        System.out.print("("+this.toString()+")" + " / " + "("+op2.toString()+")" + "=");
        return new Fraction (numer, denom);
    }

    public String toString()      //輸出格式及限定
    {
        String result;

        if (numerator == 0)               //分子為0,結果為0
            result = "0";
        else
        if(denominator == 0)              //分母不能為0
            return "錯誤!分母不能為0";
        else
        if (denominator == 1)             //分母為1,結果取分子值
            result = numerator + "";

        else
            result = numerator + "/" + denominator;  //按分數形式輸出結果

        return result;
    }

    private void reduce()
    {
        if (numerator != 0)
        {
            int common = gcd (Math.abs(numerator), denominator);    //取分子分母最大公因子

            numerator = numerator / common;                        //約分
            denominator = denominator / common;
        }
    }


    private int gcd (int num1, int num2)                      //計算最大公因子
    {
        if(num2==0)
            return num1;
        else
            return gcd(num2,num1%num2);

    }
    public static Fraction obj(){                               //生成隨機數
        Random ran = new Random();
        return new Fraction(ran.nextInt(100),ran.nextInt(100));
    }
}

測試代碼

技術分享圖片

技術分享圖片

運行結果截圖

技術分享圖片

碼雲鏈接

碼雲鏈接

實驗過程

  • 上次關於真分數的算法我們沒有弄明白。這次我們認真討論並解決了問題。關於代碼的批註在上面的代碼裏。
  • 首先是用java語言描述真分數裏的加減乘除運算,然後將運算結果化簡。
  • 化簡過程需要用到求最大公因子,這時候我們需要分子分母均為正值,於是就有了public Fraction (int numer, int denom)方法,以及Math.abs(numerator)來保證算法不出現漏洞。
  • 除此之外還要註意分子分母計算的一些限定特性。我們同樣加進代碼裏。
  • 代碼裏的去重功能沒寫出來,但是經過討論有了思路:(1)記錄之前生成的題目;(2)用遍歷比較新生成題目與舊生成題目。如果重復,則刪除此新生成題,並再生成一個題目,重新遍歷檢查。如果不重復,則進入下一環節。

評價我的結隊小夥伴

她很美
是天邊的火燒雲
是日月星辰
但是
我更美

在本周學習中,在小夥伴的幫助下,我對代碼有了更深的解讀,她的認真及更高效的學習方法讓我受益,在這周的磨合中我們的默契度也有了更大的提高,思考問題的時候,會有更多相同的思考,結對學習的過程也是我們相互促進的過程。

總結

  • 感受到了有所思路卻寫不出代碼的痛苦,有時候甚至想,為啥不用C編...好吧我的思維還沒有轉變過來。
  • 但是還是很開心,比上周又進步了一點點。開始學著用偽代碼,流程圖來描述思路給自己的小夥伴看。也讓整個算法在腦海裏有更清晰的構造。

20165322 第二周結隊編程-四則運算