結對編程(Java實現)

1、Github項目地址:https://github.com/qiannai/CreateArithmeticgit

 

2、PSP2.1表格:github

PSP2.1編程

Personal Software Process Stages數組

預估耗時(分鐘)數據結構

實際耗時(分鐘)架構

·Planningapp

·計劃dom

30函數

40性能

· Estimate

· 估計這個任務須要多少時間

30

20

·Development

·開發

300

420

· Analysis

· 需求分析 

60

50

· Design Spec

· 生成設計文檔

30

20

· Design Review

· 設計複審 

30

30

· Coding Standard

· 代碼規範

100

120

· Design

· 具體設計

60

20

· Coding

· 具體編碼

1200

700

· Code Review

· 代碼複審

20

20

· Test

· 測試(自我測試,修改代碼,提交修改)

200

100

·Reporting

·報告

100

140

· Test Report

· 測試報告

60

50

· Size Measurement

· 計算工做量

20

20

· Postmortem & Process Improvement Plan

· 過後總結, 並提出過程改進計劃

40

50

合計

 

2010

1800

3、性能分析:

一、爲了儘快的完成程序,目的保證是項目可以正確的完成,因此犧牲了許多時間。

       例如:實現整數跟分數之間的運算,是直接將分數化成假分數去運算,而不是像3+3/4能夠直接等於3’3/4 ,而是(3*4+3)/4再化成真分數運算。不過花費較多的時間去優化這一部分,雖然會快不少,代碼會有不少複雜性,並且代碼可讀性較差。

二、對程序的分析,由於答案文檔跟題目是相對應的,因此在生成題目的同時就對答案生成,採用的是左結合的方式,邊生成式子邊生成答案,因此在這裏犧牲了空間存儲。由於若是採用題目生成跟答案分開的形式,能夠對用戶是否輸入答案作出判斷,若是用戶沒有輸入答案,則直接判錯,不進行運算分析。不過這樣子雖然提升了性能,可是失去了生成答案的必要性,在答案必須生成的狀況下,則一邊生成數的方式一邊生成答案的方法能夠提供很高的性能。

//建立up之內的數的四則運算
    String[] createArithmetic(int up){//返回一個大小爲3的String數組,str[0]保存了答案,str[1]保存查重標記,str[2]保存的是一條四則運算式子
        Computed computed = new Computed();
        Sum s = new Sum();
        String[] str = new String[3]; 
        Random rand = new Random();
        int saveRand = rand.nextInt(4);
        int forNum = 0;
        String n1 = s.createNum(up);
        String n2 = s.createNum(up);
        switch(saveRand){
        case 0:
        case 1:
        case 2:str=computed.sub(n1, n2, str);break;//作加法
        case 3:
        case 4:
        case 5:str=computed.sub(n1, n2, str);break;//作減法
        case 6:
        case 7:str=computed.multi(n1, n2, str);break;//作乘法
        case 8:
        case 9:str=computed.div(n1, n2, str);break;//作除法
        }
        forNum = rand.nextInt(3);//隨機生成控制運算符數
        for(int i = 0;i<forNum;i++){
            saveRand = rand.nextInt(10);
            n1 = s.createNum(up);
            switch(saveRand){//30的機率作加減法,20的機率作乘除法
            case 0:
            case 1:
            case 2:str=computed.sub(n1, "", str);break;//作加法
            case 3:
            case 4:
            case 5:str=computed.sub(n1, "", str);break;//作減法
            case 6:
            case 7:str=computed.multi(n1, "", str);break;//作乘法
            case 8:
            case 9:str=computed.div(n1, "", str);break;//作除法
            }
        }
        return str;
    }

 

三、求最大公因數,爲了編程的簡單,因此採用了測試的方法。可是分數的使用頻率高,因此這方面花費時間高。註釋爲原先代碼,非註釋部分爲採用展轉相除法改進。

int maxCommonFactor(int r1,int r2){//求出最大公因數
        int num1 = r1<r2?r1:r2;//兩數最小
        int num2 = r1<r2?r2:r1;//兩數最大
        int temp=0;
        /*for(int i=num1;i>=1;i--){
            if(0==num1%i&&0==num2%i){
                return i;
            }
        }
        return 1;*/
        //代碼優化
        //展轉相除法
        if(num1==0)return 1;//若是分母是0,則表明該式子是被整除的,直接返回
        if(num2%num1==0){
            return num1;
        }else{
            temp=num2;
            num2=num1;
            num1=temp%num1;
        }
            return maxCommonFactor(num1, num2);//遞歸查詢
    }

 生成10000條程序所花費的時間

四、查重是一個大問題,由於你比較是否重複須要對以前的生成式子進行一個個的比較。這個地方沒有想到改善的方法,該查重的時間複雜度爲n*(n-1)/2。爲整個程序中運行時間最久的。

while(i<n){
                        b = true;
                        j++;
                        System.out.println(j);//留待測試那些相同的等式判別。
                        str =Arithmetic.this.createArithmetic(r);
                        for(String s:str_1){
                            if(str[1].equals(s)){//若是已經有了則設置爲false
                                b=false;
                            }
                            
                        }
                        if(b){//若是爲false,則表明生成的式子是重複的因此不錄入
                            str_1[i]=str[1];
                            try {
                                jta.append("文件正在寫入中\n");
                                fw_1.write("四則運算題目  " + (i+1) + ":  " + str[2]+ " = " + "\r\n");
                                fw_2.write("四則運算答案  " + (i+1) + ":  " + str[0]+ "\r\n");
                                fw_1.flush();
                                fw_2.flush();
                            } catch (IOException e1) {
                                // TODO Auto-generated catch block
                                e1.printStackTrace();
                            }
                            i++;
                        }
                        
                    }

4、設計實現過程:

 

一、對式子查重的見解:

  (1)拿到這道題以爲是比較難的,看完題的第一印象就是先無論運算結果,先隨機生成一條運算式子,再經過一種方法對整一條式子進行計算。可是我看到第六點的時候,要求必需要生成的式子必需要不一樣,我想到了標記的方法,對每一條式子作出標記。我想的標記是用運算的順序進行標記。因此我改選其餘方法生成四則運算。經過一個String[]數組保存一條式子的結果,運算順序,運算式。結果能夠用來生成結果集,運算順序用來判斷是否是兩條式子是否相同,運算式用來做爲題集。

       (2)相似:1+2跟 2+1 是相同。對運算方法標記爲1 2+。對式子排序標記。若是生成的爲1和2作了加法,跟生成的爲2和1作加法,同理其標記式爲相同。

       (3)一開始以爲1+2+3跟1+3+2是一條相同的式子,就有對每一次作加法的時候判斷上一次是否作了加法(取上一次的運算順序的最後一個符號)對整條式子進行排序。發現作法很麻煩,想着用一開始的方法去作,(即隨機生成一條式子,再經過式子計算結果)而後用結果做爲標識符,只有出現不一樣的結果才錄入。不過以爲去除的式子太多了。(後面仍是想到了一種很好的方法,就是將全部的式子全部的運算數排序,先比較結果,結果同樣,再比較運算數的排序,同樣則去除式子)(然而已經作完了,因此就不去用這個方法了,能夠把運算符也進行排序,作第三次判斷。我的認爲是比較好的方法,由於在這種判斷之下,1+2+3跟3+2+1也能夠去除,雖然按照左結合的方法,是不一樣的式子)

       (4)由於判斷是左結合的方法,則1+2+3跟3+2+1運算順序保存形式分別爲1 2+ 3+跟   2 3+ 1+兩種標誌,比較結果應該是不一樣的。在生成1+2+3跟3+(1+2)的時候,由於使用的是左結合的方式生成式子,在Arithmetic中的createNum()生成的加法會將+左右兩端隨機調換,故兩式的運算順序標記都是1 2+ 3+,若是同時出如今後續的判斷中會將這一類的式子剔除。由於式子是左結合的,因此只要運算順序不同,則一定是兩條不一樣的式子。

二、具體思路:

對查重有了正確的想法就須要肯定式子具體的生成和對整個項目的實現。在這裏我就採用了自底向上跟自頂向下的方法對整個項目進行架構。使用生成一條正確的式子和答案和運算順序做爲分界點,自底向上的最終結果是生成一條完整式子,自頂向下是外部用戶界面到對一條式子的使用。

三、自底向上的開發:

(1)針對的是對一條式子的生成,生成一條式子,須要對式子進行計算。一條四則運算根據運算順序爲左結合的方式,左結合的方式爲對一個運算符兩端進行計算,即每次都是對兩個數進行計算,因此要計算一條式子,首先要完成兩個數之間的運算。

       (2)具體能夠分爲整數跟整數的運算,整數跟分數的運算,分數跟分數的運算。運算包括了加減乘除。因此我創建了一個類Sum對寫了12個運算,分別爲:整數跟整數的加法,整數跟分數的加法,分數跟分數的加法……

       (3)實現了12個計算後,若是直接使用實際上是比較麻煩的,由於要對輸入的數進行整數分數判斷。因此必須對其整合成數跟數的計算。創建一個add_nan(String n1,String n2)方法對n1跟n2兩個數進行判斷兩個數是分數仍是整數,判斷後調用相對應的計算方法,同理,其餘的運算符也是如此。

       (4)對於含分數的加法,其實能夠直接的使用帶分數的整數跟整數相加減,分數跟分數相加減。雖然這是正常的計算方式,可是對於計算來講,須要對數進行判斷是比較麻煩的。因此直接將分數化爲假分數,經過運用假分數進行計算,最後將假分數化爲真分數就能夠實現分數之間的運算。

       (5)對於減法有點的不一樣,必需要相減爲正數,因此在作減法的時候經過創建is1max2(String r1,String r2)的方法判斷兩個數是否r1>r2,結果爲返回減法後的絕對值。

      

在這裏就實現了數與數之間的算術。

       Sum類中包含了{12個整整,整分,分分之間的加減乘除,4個數與數之間的加減乘除,1個將分數化爲假分數,1個假分數化爲真分數,1個計算最大公因數,1個產生一個隨機分數或整數的方法}

       在這裏就構成了底層函數,造成計算結果,這爲產生一個四則運算式的一期工做。

      

       (6)這只是計算式子答案,在Computed類中創建了add,sub,multi,div四個方法,調用Sum中的計算方法得出結果,在方法中統一用(String r1, String r2, String[] t)的接口。

r1爲每次生成的左結合隨機數,若是t[0]爲空,則表明是第一次計算,其進行計算的隨機數爲r1跟r2兩個隨機數,若是t[0]不爲空,則證實是進行了第二次計算。

       其中t[]爲三個String組成的數組,t[0]表明上一次計算的結果,t[1]表明上一次計算的順序,t[2]表明上一次的運算式子。

       經過輸入生成對應的式子。在Arithmetic類中有一個String[] createArithmetic(int up)方法,爲建立一條四則運算的式子,up表示生成數的範圍。up傳參到CreateNum方法中生成隨機數。經過隨機選取運算方式生成一條四則運算式子。這就完成了第二期任務。

      

       注:由於有了上一次我的設計的經驗,在這裏中,提早作好了接口規範,一開始就用String類型保存數字。對於同類型的方法統一用一樣的數字類型。因此在後續的合成一條式子中,用t數組保存了,生成答案的t[0],用於判斷是否重複的t[1],用於生成題集的t[2]。保證了後續的使用不用回來修改接口的問題,節省大量時間的代碼優化。

 

四、生成一條四則運算的式子後,應該要從用戶進入界面入手,一步步到使用生成的四則運算式子。開始設計用戶使用界面:

       (1)命令行的輸入,作成可視化界面後,對用戶的輸入用JTextField的一行輸入,對於各類錯誤還有運行的信息用一個文本框來輸出提示,提示的文本框並不是給用戶編輯的。對於輸入的命令須要設置監視器,用一個按鈕對命令輸入框進行監控。

       (2)運行完-n和-r的命令以後,將生成一個問題的txt文件和一個保存題目答案的文件。對於這兩個文件用兩個按鈕綁定,點擊按鈕會打開生成的問題或者是生成答案的文件。

       (3)對作完的題目須要生成成績,設置一個計算成績的按鈕,點擊按鈕將讀取問題的答案和標準答案進行比較,由於沒法預計用戶對計算成績的操做進行亂輸入,設置成按鈕,保證能夠計算的是同一份文件的成績。

       (4)一樣能夠點擊打開成績按鈕查看保存爲txt文件的計算後的成績。

       (5)爲了用戶的更容易使用,文件的保存位置能夠是自定義的,因此代碼中不保存保存路徑,須要從用戶獲取,創建一個visualGetPath()方法,打開一個用戶路徑獲取的可視化界面。

該方法爲程序一開始運行彈出,配置完成後,才調用visual()方法,打開用戶使用界面。對於用戶輸入的路徑錯誤,則設立了一個按鈕用於修改保存路徑,當點擊按鈕,調用visualGetPath()方法,再點擊完成,關閉上一個用戶使用界面,打開新的用戶使用界面,若是點擊返回,則不作任何變化。

       (6)設置一個軟件關閉按鈕,點擊按鈕,將關閉全部的程序。

       (7)設置一個幫助按鈕,點擊按鈕彈出用戶使用幫助框。

 

5、代碼說明:以加法爲例,其餘運算符的運算方式與加法運算類似

一、兩個數的加法,對不一樣的輸入進行區分,調用對應的辦法。

public String add_nan(String n1,String n2){//兩個數相加的值
        String sum = "";
        if(Pattern.matches(".+\\/.+", n1)){//n1是分數
            if(Pattern.matches(".+\\/.+", n2)){//n1是分數,n2是分數
                sum = this.add_faf(n1, n2);
            }else{//n1是分數,n2是整數
                sum = this.add_faz(n1, n2);
            }
        }else{//n1是整數
            if(Pattern.matches(".+\\/.+", n2)){//n1是整數,n2是分數
                sum = this.add_faz(n2, n1);
            }else{//n1是整數,n2是整數
                sum = this.add_zaz(n1, n2);
            }
        }
        
        return sum;
    }

 

二、整數跟整數加法

public String add_zaz(String z1,String z2){//兩個整數相加
        String sum ="";
        int s = 0;
        int i1 = Integer.parseInt(z1);
        int i2 = Integer.parseInt(z2);
        s = i1 + i2;
        sum+=s;
        return sum;
    }

 

三、分數跟分數加法

public String add_faf(String r1,String r2){//兩個分數相加
        int[] i1 = new int[2];
        int[] i2 = new int[2];
        int[] s = new int[2];
        String sum ="";
        i1 = this.falseFaction(r1);
        i2 = this.falseFaction(r2);
        s[0]=i1[0]*i2[1]+i2[0]*i1[1];
        s[1]=i1[1]*i2[1];
        sum = this.trueFaction(s);
        return sum;
    }

 

四、分數跟整數加法

public String add_faz(String f,String z){//分數與整數相加,返回一個String和
        String sum = "";
        int[] i1 = new int[2];
        int   i2 = Integer.parseInt(z);
        i1 = this.falseFaction(f);
        i1[0] = i2*i1[1]+i1[0];
        sum = this.trueFaction(i1);
        return sum;
    }

 

五、化爲真分數

String trueFaction(int[] flaFac){//化爲真分數
        String s="";
        int k = 0;
        int fenzi = 0;
        int maxCom =1;
        fenzi =flaFac[0]%flaFac[1];//若是是整除,則爲0
        maxCom = this.maxCommonFactor(fenzi, flaFac[1]);//分數之間最大公因數
        k=flaFac[0]/flaFac[1];//整除,則k爲整數
        fenzi/=maxCom;
        flaFac[1]/=maxCom;
        if(fenzi==0){
            s+=k;
        }else{
            if(k==0){
                s+=fenzi+"/"+flaFac[1];
            }else{
                s+=k+"'"+fenzi+"/"+flaFac[1];
            }
        }
        return s;
    }

 

六、化爲假分數

int[] falseFaction(String f){//將一個分數換成分子除分母的int型,0爲分子,1爲分母
        String[] cutF =new String[3];
        int[] fract = new int[3];
        int[] falseFac = new int[2];
        if(Pattern.matches(".*\\'.*",  f)){
            cutF = f.split("\\/|\\'");
            for(int i=0;i<cutF.length;i++){
                fract[i]=Integer.parseInt(cutF[i]);
            }
            falseFac[0]=fract[0]*fract[2]+fract[1];
            falseFac[1]=fract[2];
        }else{
            cutF = f.split("\\/");
            for(int i=0;i<cutF.length;i++){
                fract[i]=Integer.parseInt(cutF[i]);
            }
            falseFac[0]=fract[0];
            falseFac[1]=fract[1];
        }
        
        return falseFac;
    }

 

七、求最大公因數

int maxCommonFactor(int r1,int r2){//求出最大公因數
        int num1 = r1<r2?r1:r2;//兩數最小
        int num2 = r1<r2?r2:r1;//兩數最大
        int temp=0;
        /*for(int i=num1;i>=1;i--){
            if(0==num1%i&&0==num2%i){
                return i;
            }
        }
        return 1;*/
        //代碼優化
        //展轉相除法
        if(num1==0)return 1;//若是分母是0,則表明該式子是被整除的,直接返回
        if(num2%num1==0){
            return num1;
        }else{
            temp=num2;
            num2=num1;
            num1=temp%num1;
        }
            return maxCommonFactor(num1, num2);//遞歸查詢
    }

 

八、產生子式子(生成答案,用於查重標記,式子)

//t數組的值爲"結果"+"排序"+"格式"
    //r1爲隨機值整數,r2爲隨機整數
    String[] add(String r1,String r2,String[] t){
        String[] ans = new String[3]; //返回值,0="結果";1="排序";2="格式"
        if(t[0]!=null){//短式的加法
            ans[0] = s.add_nan(r1, t[0]);
            if(Pattern.matches(".+(\\+|\\-)", t[1])){
                saveRand = rand.nextInt(100);
                if(saveRand>=70){//r1 =1;t[0]=2+3;30的機率作1+(2+3)的變換,70的機率爲2+3+1
                    ans[2] = r1 + " " + "+" + " " + "(" + t[2] + ")";
                }else{
                    ans[2] = t[2] + " " + "+" + " " + r1;
                }
            }else{//若是是乘法則不須要加括號,直接交換順序
                saveRand = rand.nextInt(100);
                if(saveRand>=70){
                    ans[2] = r1 + " " + "+" + " " + t[2];
                }else{
                    ans[2] = t[2] + " " + "+" + " " +r1;
                }
            }
            ans[1] =t[1] + " " + r1 + "+";
        }else{//r2與r1 的加法
            ans[0] = s.add_nan(r1, r2);
            if(s.is1max2(r1, r2)){//標識爲高到低
                ans[1]=r1 + " " + r2 + "+";
            }else{
                ans[1]=r2 + " " + r1 + "+";
            }
            ans[2]=r1 + " " + "+" + " " + r2;
        }
        return ans;
    }

 

九、隨機生成式子

//建立up之內的數的四則運算
    String[] createArithmetic(int up){//返回一個大小爲3的String數組,str[0]保存了答案,str[1]保存查重標記,str[2]保存的是一條四則運算式子
        Computed computed = new Computed();
        Sum s = new Sum();
        String[] str = new String[3]; 
        Random rand = new Random();
        int saveRand = rand.nextInt(4);
        int forNum = 0;
        String n1 = s.createNum(up);
        String n2 = s.createNum(up);
        switch(saveRand){
        case 0:
        case 1:
        case 2:str=computed.sub(n1, n2, str);break;//作加法
        case 3:
        case 4:
        case 5:str=computed.sub(n1, n2, str);break;//作減法
        case 6:
        case 7:str=computed.multi(n1, n2, str);break;//作乘法
        case 8:
        case 9:str=computed.div(n1, n2, str);break;//作除法
        }
        forNum = rand.nextInt(3);//隨機生成控制運算符數
        for(int i = 0;i<forNum;i++){
            saveRand = rand.nextInt(10);
            n1 = s.createNum(up);
            switch(saveRand){//30的機率作加減法,20的機率作乘除法
            case 0:
            case 1:
            case 2:str=computed.sub(n1, "", str);break;//作加法
            case 3:
            case 4:
            case 5:str=computed.sub(n1, "", str);break;//作減法
            case 6:
            case 7:str=computed.multi(n1, "", str);break;//作乘法
            case 8:
            case 9:str=computed.div(n1, "", str);break;//作除法
            }
        }
        return str;
    }

 

十、重複式子去除

int i =0;
                    String[] str_1 = new String[n];//建立大小爲n條式子的存儲空間,用於保存查重
                    boolean b = true;
                    int j=0;
                    while(i<n){
                        b = true;
                        j++;
                        System.out.println(j);//留待測試那些相同的等式判別。
                        str =Arithmetic.this.createArithmetic(r);
                        for(String s:str_1){
                            if(str[1].equals(s)){//若是已經有了則設置爲false
                                b=false;
                            }
                            
                        }
                        if(b){//若是爲false,則表明生成的式子是重複的因此不錄入
                            str_1[i]=str[1];
                            try {
                                jta.append("文件正在寫入中\n");
                                fw_1.write("四則運算題目  " + (i+1) + ":  " + str[2]+ " = " + "\r\n");
                                fw_2.write("四則運算答案  " + (i+1) + ":  " + str[0]+ "\r\n");
                                fw_1.flush();
                                fw_2.flush();
                            } catch (IOException e1) {
                                // TODO Auto-generated catch block
                                e1.printStackTrace();
                            }
                            i++;
                        }
                        
                    }
                    

6、測試運行:

一、獲取工做路徑,若是一開始沒有得到路徑,不能返回,路徑正確後完成則進入程序運行界面。默認路徑爲D:/

二、輸入-n 10000後輸入-r 10 ,獲取生成條數,生成數的範圍

三、運行後生成題目,和答案,點擊打開問題或者答案能夠直接打開對應文件

四、完成題目答案後,點擊check Answer能夠對文件打分,並生成答案文檔,不過須要先對撰寫答案後的題目文件進行保存後運行。點擊open Grade能夠打開查當作績。在第四五題填寫正確答案,第七題填錯誤答案,第674,8016,8017題填寫正確答案,第8742題填寫錯誤,第9997題填寫正確,其他不填寫

五、編寫答案文件,並檢查用例

六、對計算的測試代碼

Sum s = new Sum();
        String[][] str = {{"4","9"},{"3/4","5/9"},{"7","4/7"},{"4/9","3"},{"2'3/4","5'3/7"},{"3","4'2/3"},{"2'3/5","3"},{"3'2/3","2/3"}};
        //保存{整數跟整數,分數跟分數,整數跟分數,分數跟整數,帶分數跟帶分數,整數跟帶分數,帶分數跟整數,帶分數跟分數}
        for(String[] sl:str){
            System.out.println(sl[0] + "+" + sl[1] + " : " + s.add_nan(sl[0], sl[1]));
            System.out.println(sl[0] + "*" + sl[1] + " : " + s.multi_nan(sl[0], sl[1]));
            System.out.println("|" + sl[0] + "-" + sl[1] + "|" + " : " + s.sub_nan(sl[0], sl[1]));
            System.out.println(sl[0] + " / " + sl[1] + " : " + s.div_nan(sl[0], sl[1]));
            System.out.println();
        }
        System.out.println("4跟9:"+s.maxCommonFactor(4, 9));
        System.out.println("3跟9:"+s.maxCommonFactor(3, 9));
        System.out.println("15跟9:"+s.maxCommonFactor(15, 9));
        int[] flaFac={27,18};
        System.out.println("27/18化爲真分數:"+s.trueFaction(flaFac));

 

七、運行結果。

子代碼運行計算正確,而且由上面生成產生子式子,與五、6中的代碼能夠看出運行的正確性,而且計算遵循左結合的方式進行。

八、重複代碼去除

從運行結果能夠看出程序產生了12067條式子,實際生成式子爲10000條。由代碼分析那裏有具體查重分析,去除掉了2000條重複代碼,在去重的代碼中插入了在while語句中檢查重複多少次的計數器j,並將之在控制檯輸出

九、計算過程當中不產生負數

String[] sub(String r1,String r2,String[] t){
        String[] ans = new String[3]; //返回值,0="結果";1="排序";2="格式"
        if(t[0]!=null){//短式的減法
            ans[0] = s.sub_nan(r1,t[0]);
            if(Pattern.matches(".+(\\+|\\-)", t[1])){//若是上一次作的是加減變換須要加括號
                if(s.is1max2(r1, t[0])){
                    ans[2]= r1 + " " + "-" + " " + "(" + t[2] + ")";
                }else{
                    ans[2]= t[2] + " " + "-" + " " + r1;
                }
            }else{
                if(s.is1max2(r1, t[0])){//r1大於短式
                    ans[2]= r1 + " " + "-" + " " + t[2];
                }else{
                    ans[2]=t[2] + " " + "-" + " " +r1;
                }
            }
            ans[1] = t[1] + " " + r1 + "-";
        }else{//r1跟r2的減法
            ans[0] = s.sub_nan(r1,r2);
            if(s.is1max2(r1, r2)){//r1>r2
                ans[1] = r1 + " "+ r2 +"-";
                ans[2] = r1 + " " + "-" + " " + r2;
            }else{
                ans[1] = r2 + " "+ r1 +"-";
                ans[2] = r2 + " " + "-" + " " + r1;
            }
        }
        return ans;
    }

對生成運算的兩個數進行比較,運算結果爲絕對值,則生成的運算式,爲大數減去小數

boolean is1max2(String r1,String r2){//比較兩個隨機數的大小,若是r1>r2;則返回true
        int[] i1 = new int[2];
        int[] i2 = new int[2];
        double d1 = 0;
        double d2 = 0;
        if(Pattern.matches(".+\\/.+", r1)){//r1是分數
            i1=this.falseFaction(r1);//化爲假分數
            d1=(double)i1[0]/(double)i1[1];//化成小數
        }else{//r1是整數
            d1 = Integer.parseInt(r1);
        }
        if(Pattern.matches(".+\\/.+", r2)){//r2是分數
            i2=this.falseFaction(r2);
            d2=(double)i2[0]/(double)i2[1];
        }else{//r1是整數
            d2 = Integer.parseInt(r2);
        }
        if(d1>d2){
            return true;
        }
        return false;
    }

 

十、運算符不超過3個控制,修改隨機數能夠隨機生成含有更多運算符的式子

forNum = rand.nextInt(3);//隨機生成控制運算符數
        for(int i = 0;i<forNum;i++){
            saveRand = rand.nextInt(10);
            n1 = s.createNum(up);
            switch(saveRand){//30的機率作加減法,20的機率作乘除法
            case 0:
            case 1:
            case 2:str=computed.sub(n1, "", str);break;//作加法
            case 3:
            case 4:
            case 5:str=computed.sub(n1, "", str);break;//作減法
            case 6:
            case 7:str=computed.multi(n1, "", str);break;//作乘法
            case 8:
            case 9:str=computed.div(n1, "", str);break;//作除法
            }
        }

 

十一、運算結果若是爲分數則用爲真分數,在代碼說明5化爲真分數有進行說明

至此功能所有完成

7、項目小結:

沒有使用數據結構去識別一條式子進行運算得出答案,而是採用邊生成式子邊生成答案的方法,雖然按照這個題目來講,其實按照迭代運算式產生一條式子是比較快的,由於生成的過程都是可控的。不過一直感受鑽了空子,跳過了對式子的識別過程,直接進行運算。不過若是能夠作出對一條式子的讀取,之後能夠對任意一條式子均可以計算出答案。可是考慮到實際運行的速度問題,產生式子與答案同時產生是一種比較快的方法。

相關文章
相關標籤/搜索