第四周-四則運算試題生成

做業具體要求連接:https://edu.cnblogs.com/campus/nenu/SWE2017FALL/homework/997android

具體實現功能以下:ios

功能1:支持出題4個數的四則運算題目,全部題目要求做者有能力正確回答。(+10)git

功能2:在功能1的基礎上,支持括號。(+15)web

功能3:限定題目數量,「精美」打印輸出,且要避免重複,最好能輸出到.txt文件中。且對輸入題目數進行限定,題目數量必須是正整數。(+10)算法

功能4:支持分數出題和運算。(不完成此題不倒扣分數)編程

功能5:可把程序改爲GUI版/web版/移植爲android,ios版。dom

這次做業完成是以「結對編程」的形式完成,個人夥伴是劉淑霞,她的博客地址爲:http://www.cnblogs.com/liusx0303/學習

 

這篇博客主要由以下幾個方面講述:spa

1.每一個功能的重點,難點。.net

2.如何解決重點難點以及收穫

3.運行截圖

4.結對編程體會。

5.合做過程。

6.版本控制。

 

一,每一個功能的重點,難點

      (1)功能一的重點難點

           重點難點1:應該選擇什麼樣的輸入,操做數和運算符隨機產生仍是用戶本身輸入,若是隨機產生要如何操做,若是用戶本身輸入要以什麼樣的形式輸入
           重點難點2:如何處理四則運算算式。
           重點難點3:將輸入的結果與正確結果比較,而後按照要求輸出。
     (2)功能二的重點難點
           功能二的要求:在功能一要求的基礎上加上有括號的運算。
           重點難點:加上有括號的運算,咱們當初分析的時候是用括號匹配的方法,括號優先級最高,優先算括號裏面的算式。
     (3)功能三的重點難點
            功能三的要求:輸入題目道數,而後輸出四則運算算式以及結果到.txt文件中,注意輸出結果右對齊,與算式有必定的距離。
            重點難點:將輸出放到.txt文件中。
     (4)  功能四的重點難點
            功能四的要求:支持分數運算,不加括號,輸出也是用分數的形式輸出,例如1/2 + 2/3 +1+1=3 1/6。
            重點難點:支持分數運算,經過通分來進行運算,結果是最簡分數(幾又幾分之幾)。

二,合做中如何解決重點難點以及收穫

         (1)功能一:

           由於要支持出題4個數的四則運算題目,針對的用戶是初中生,因此題目難度不能太過於簡單,也不能過於困難。若是題目隨機生成,有太大的隨機性,且容易產生重複,用隨機數自動生成四個數的四則運算也會比較麻煩,考慮的狀況會比較繁多。開始,咱們用random生成兩個數加減乘除的運算,運行成功,實現支持4個數的四則運算的時候,由於要考慮的狀況太過於複雜,寫完就400多行代碼了,且題目易重複。想一想功能一實現就這樣艱難。因而想經過本身輸入出題,而後讓人作的形式實現,且本身出題能夠避免重複。題以字符串的出現,而後對字符串進行處理,而後對題進行計算。

對字符串進行處理,判斷表達式格式是否正確的代碼實現以下:

//檢查表達式格式是否正確
     public static boolean checkFormat(String str)
     {
            // 校驗是否以「=」結尾
            if ('=' != str.charAt(str.length() - 1))
            {
                return false;
            }
            // 校驗開頭是否爲數字或者「(」
            if (!(isCharNum(str.charAt(0)) || str.charAt(0) == '('))
            {
                return false;
            }
            char c;
            // 校驗
            for (int i = 1; i < str.length() - 1; i++) 
            {
                c = str.charAt(i);
                if (!isCorrectChar(c))
                {// 字符不合法
                    return false;
                }
                if (!(isCharNum(c))) {
                    if (c == '-' || c == '+' || c == '*' || c == '/') {
                        if (c == '-' && str.charAt(i - 1) == '(')
                        {// 1*(-2+3)的狀況
                            continue;
                        }
                        if (!(isCharNum(str.charAt(i - 1)) || str.charAt(i - 1) == ')')) 
                        {// 若符號前一個不是數字或者「)」時
                            return false;
                        }
                    }
                    if (c == '.') 
                    {
                        if (!isCharNum(str.charAt(i - 1)) || !isCharNum(str.charAt(i + 1))) 
                        {// 校驗「.」的先後是否位數字
                            return false;
                        }
                    }
                }
            }
            return isBracketCouple(str);// 校驗括號是否配對
        }

         (2)功能二:

           對於在功能一的基礎上,實現括號。咱們是利用棧實現括號匹配算法。而且使用了map對運算符進行了優先級處理。

符號的優先級處理代碼以下:

public static final Map<Character, Integer> symLvMap = new HashMap<Character, Integer>();// 符號優先級map
    static 
    {
            symLvMap.put('=', 0);
            symLvMap.put('-', 1);
            symLvMap.put('+', 1);
            symLvMap.put('*', 2);
            symLvMap.put('/', 2);
            symLvMap.put('(', 3);
            symLvMap.put(')', 1);
     }

括號匹配的代碼以下:

//校驗括號是否配對
     public static boolean isBracketCouple(String str) 
     {
            LinkedList<Character> stack = new LinkedList<Character>();
            for (char c : str.toCharArray()) 
            {
                if (c == '(') 
                {
                    stack.add(c);
                } else if (c == ')') 
                {
                    if (stack.isEmpty()) 
                    {
                        return false;
                    }
                    stack.removeLast();
                }
            }
            if (stack.isEmpty()) 
            {
                return true;
            } else 
            {
                return false;
            }
        }

 

         (3)功能三:

          1.對於輸入題目道數是正整數的判斷,不能是英文(test),負數(-100),浮點數(3.5)。開始是定義了一個int型的變量,而後對變量進行正整數判斷,把負整數去掉。

可是當輸入英文,負數和浮點數的時候,運行的時候報錯了。後來採用字符串的格式進行輸入,而後對字符串的進行在數值範圍的判斷。

判斷輸入題目道數是正整數的代碼以下:

//判斷輸入的題目數是否爲正整數
     public boolean judgeInput(String str)
     {
        boolean flag=true;
        for(int j=0;j<str.length();j++)
         {
             if(!(str.charAt(j)>=48&&str.charAt(j)<=57))
             {
             System.out.println("題目數量必須是 正整數。");
             flag=true;
             break;
             }
             else 
             {
                 flag=false;
             }
         }
        return flag;
        
     }

           2.將題目和答案輸出到.txt文件中

實現代碼以下:

 //將表達式寫入文件answer.txt
             try 
             {
                  if (!file.exists()) 
                  {
                        file.createNewFile();
                  }
                  FileWriter writer = new FileWriter(file,true);
                  if(true)
                  {
                        results = System.getProperty("line.separator")+results;
                  }
                  writer.write(results);
                  writer.flush();
                  writer.close();
             } 
             catch (IOException ex)
             {
                  ex.printStackTrace();
             }

         (4)功能四:

         方法是先求出兩個分數分母的最小公倍數,通分後,再對兩個分子的加減乘除,最後約簡結果分數的分子和分母,即用分子分母的最大公約數分別除分子和分母。再按順序輸入分子和分母,在控制檯上輸出其運算結果。

求最大公約數的代碼以下:

 static int gcd(int m,int n)
{
int t,r;//展轉相除法 if(m < n) { t = m; m = n; n = t; } while(n != 0) { r = m%n; m = n; n = r; } return m; }

求最小公倍數代碼以下:

static int lcm(int m,int n)
{
int i = gcd( m,n); int j = (m/i)*(n/i)*i; return j; }

收穫:

1.在制定代碼規範的時候,由於咱們都有本身的習慣,因此在制定規則時討論了較長時間,可是彼此爲對方考慮,都各自讓步,最終制定了兩我的都能接受的代碼風格規範。這告訴咱們,要多爲對方考慮一點,這樣才能使合做更愉快,後面實現的過程當中也證實了這一點。

2.在考慮實現出題的時候,我和霞都不約而同的用隨機數生成出題。以爲可簡單了,認爲一兩個小時就能完成功能一,開始實現起來兩個數的加減乘除很快就完成了,而後按照老師要求要完成四個數的加減乘除,實現起來狀況就很複雜了,咱們完成一個demo的時候就差很少500行代碼了,花費了3個多小時,而且有出題重複的狀況。後來就一塊兒討論用本身出題的方式解決,能夠避免重複,而且能夠控制難度。實現的過程,咱們讓結果返回double,由於除法確定會有小數的出現。在一塊兒討論實現的過程當中,知道了不要把一個問題看得太簡單,否則容易眼高手低,要明白需求,再開始作事。

3.在對輸入題目以字符串的形式寫表達式時,要對輸入的表達式作各類判斷,否則表達式會出錯,操做數是否是數字,操做數是否是「+,-,*,/」,最後是否是以等號結尾。一我的老是會疏忽不少小細節,幸運的是,我和霞結對編程,總能考慮到對方疏忽的一些小問題。

4.在結對編程的過程當中,一我的在編,另一我的在旁邊盯着,老是可以及時提醒對方觸犯的代碼規範和犯的語法錯誤,相互批評,指導,和交流,比一我的編程好玩多了,編程速度雖然沒有一我的快,可是兩我的編程的質量更高,錯誤更少。

5.功能3將結果輸出到.txt文件中,運行輸入表達式的時候,打開.txt文件一看結果都在,覺得本身成功了,可是可開心了,而後霞察覺文件的表達式不少,且有重複,咱們恍然大悟,知道本身原始數據沒有清空,而後兩我的尋找解決對策,後來決定在輸入題目語句後面將.txt賦空值,兩我的一塊兒發現和解決問題的過程真是很nice。

 

三,運行截圖

功能1,2截圖

功能3截圖:

 

 

 

 

四,結對編程體會

結對編程以前,我並無發現結對編程的好處,但在共同完成做業的時候,切身感覺到結對編程的好處。兩人合做的過程,是一段「美好且痛苦又幸福」的體驗。

在四個功能的實現過程當中,咱們碰見了不少沒有想到的困難。在碰見一個難點的時候,或者運行時出錯的時候,兩我的一塊兒想辦法解決,兩我的雖然都有不同的想法,可是都是爲了解決同一個問題,當誰的辦法可以解決問題的時候,咱們都特別開心。完成做業的同時,我得到了知識,也從對方的身上學到了不少,學習能力和思惟方式都獲得了進步,發現結對編程會使兩我的加在一塊兒,會達到1+1>2的效果。

 

五,合做過程

咱們結對編程是在軟件所220完成,附上咱們兩人結對編程的照片。

 

六,版本控制

git地址:https://coding.net/u/huyr000/p/FourArithmetic/git

相關文章
相關標籤/搜索