OO第一单元总结__多项式求导问题
?
作業一、含冪函數的簡單多項式的求導
(1)基于度量的程序結構分析
1. 統計信息圖:
2. 結構信息圖:
?
3.?復雜度分析
基本復雜度(Essential Complexity (ev(G))、模塊設計復雜度(Module Design Complexity (iv(G)))、Cyclomatic Complexity (v(G))圈復雜度
?
OCavg為平均循環復雜度;WMC為總循環復雜度
4. 分析:
本次作業一共使用3個類,沒有使用繼承、接口。
Main類:
1)程序入口
2)主要業務邏輯層
3)處理輸入String
Polynomial類:處理多項式
1)正則表達式判WF(大正則)
2)簡化輸入String
3)分解成單項式:
用ArrayList<String>儲存
3)組合單項式的輸出String:
最終將ArrayList<String>轉為String
4)簡化輸出String
Deviation類:單項式求導
1)求導
2)生成輸出String
?
(2)程序BUG分析
1. 強測中未被查出BUG,但由于-1*cos(x)未被簡化成-cos(x),被扣了性能分。
| 輸入 | 我的輸出 | 原因 |
| ?-sin(x)? | ?-1*cos(x)? | 在優化時只優化了+1*x-->+x,忘記了-1的情況,并且測試也不全面 |
2. 互測中未被查出BUG
?
(3)程序測試分析
1. 本次作業同學們的BUG集中在WF方面,/f,/v,+,**,末尾加空格等情況可能沒有判出WF(BUG類似,不一一列舉)。
2. 個人覺得一個有效解決非法字符的辦法是先將正確字符從輸入表達式中刪除,再判斷輸入是否為空,不為空則WF。
3. 本次測試方法是構造各種WF的數據。
?
?
作業二、含三角函數的普通多項式的求導
(1)基于度量的程序分析
1. 統計信息圖:
2. 結構信息圖:
3. 復雜度分析
基本復雜度(Essential Complexity (ev(G))、模塊設計復雜度(Module Design Complexity (iv(G)))、Cyclomatic Complexity (v(G))圈復雜度
OCavg為平均循環復雜度;WMC為總循環復雜度
4. 分析:
本次作業一共使用4個類,沒有使用繼承、接口。
Main類:
1)程序入口
2)主要業務邏輯層
InputHandler類:
1)處理輸入String
2)少部分判WF
3)簡化輸入String
Polynomial類:處理多項式
1)大部分判WF(大正則)
2)分解成單項式:
用ArrayList<String>儲存
3)組合單項式的輸出String:
最終將ArrayList<String>轉為String
4)簡化輸出String:
合并同類項,去0項,去1*,去-1*,找到正項做首項并去掉+,?cos(x)^2+sin(x)^2?合并(任意系數的可合并項)
Monomial類:處理單項式
1)合并同類項
合并后形如?a*x^b*sin(x)*c*cos(x)^d?
2)求導:
對于一個單項式,設其為a*x^b*sin(x)*c*cos(x)^d,再設其導數為A1*x^B1*sin(x)*C1*cos(x)^D1 + A2*x^B2*sin(x)*C2*cos(x)^D2 + A3*x^B3*sin(x)*C3*cos(x)^D3,通過數學運算可求出各參數值。
3)生成輸出String
?
(2)程序BUG分析
1.? 強測中未被查出BUG,但由于只做了一部分優化,被扣了性能分。
? e.g. ?sin(x)^3*cos(x)+sin(x)*cos(x)^3?可化簡為-->?sin(x)*cos(x)?,但是這種化簡比較復雜,我為了保證正確沒有實現。
2. 互測中未被查出BUG
?
(3)程序測試分析
測試方法:我用之前構造的測試樣例先大致測試一遍,在觀察一些易考察的部分(如:正則表達式),進行針對性測試。
? 本次debug情況如下:
| 輸入 | 輸出 | 原因 |
| ? sin(x) * sin(x) * cos(x) ^-2 *x ? | ?WRONG FORMAT!? | 無法識別多個三角函數連乘 |
?
?
作業三、支持嵌套的復雜多項式的求導
(1)基于度量的程序分析
1. 統計信息圖:
?
2. 結構信息圖:
??
3. 復雜度分析
基本復雜度(Essential Complexity (ev(G))、模塊設計復雜度(Module Design Complexity (iv(G)))、Cyclomatic Complexity (v(G))圈復雜度
OCavg為平均循環復雜度;WMC為總循環復雜度
4. 分析
本次作業一共使用10個類,沒有使用接口,使用了一層繼承。
Main類:
1)程序入口
2)主要業務邏輯層
?InputHandler類:
1)處理輸入String
2)部分WF
factors包:
Factor類(父類):
1)抽象函數derivation?public abstract String derivation();?
2)FactorTri類(三角函數因子類):
2.1)將嵌套的因子用?content?保存:
?content = string.replaceAll("^sin\\(", "").replaceAll("\\)(\\^[+\\-]?\\d+)?$", "");?
2.2)區分sin、cos?private Pattern patternSin = Pattern.compile("^sin\\(");
??private Pattern patternCos = Pattern.compile("^cos\\(");
2.3)判斷WF(指數>10000)
2.4)求導
3)FactorX類(冪函數因子類):
3.1)求導
items包:
CombinationItem類(父類):
1)定義最大遞歸深度(將非法數據判為WF)(每調用一次depth++):
1 if (depth > 95) { 2 System.out.println("WRONG FORMAT!"); 3 System.exit(0); 4 }2)定義抽象函數derivation?public?abstract?StringBuilder derivation();?
3)定義函數beakdown,將str以sign分割為List?ArrayList<String> breakDown(String str, String sign)?,并判斷WF
4)ItemAdd類(加法組合項類):
4.1)?ArrayList<String> addList = breakDown(string, "+-");?
4.2)對addList每一項判斷
4.2.1)若string為表達式因子之外的因子,直接求導,以stringBuilder返回值
4.2.2)其他情況調用itemMultiIply類,進入下一輪遞歸調用
1 ItemMultiIply itemMultiIply = new ItemMultiIply(addList.get(i), depth + 1); 2 stringBuilder.append(itemMultiIply.derivation());5)ItemMultilply類(乘法組合項類):
5.1)?ArrayList<String> multList = super.breakDown(string, "*");?
5.2)鏈式求導,調用itemNesting類
6)itemNesting類(嵌套組合項類):
6.1)判斷是否有嵌套,同時判斷WF
6.2)若有()類嵌套,調用itemAdd類
6.3)若有sin()、cos()類嵌套
6.3.1)如果內含為表達式因子之外的因子則直接返回stringBuilder
6.3.2)否則調用itemAdd類(用多flag參數的構造函數并設flag=1)和FactorTri類
6.4)其他情況
6.4.1)flag = 0則調用itemAdd類
6.4.2)flag = 1則WF
OutputHandler類:
1)防止輸出空字符串
2)輸出String
?
(2)程序BUG分析
1.? 強測中未被查出BUG,但為了保證正確性,沒有做優化,性能分為0。
2. 互測中被查出1個BUG,如下:
| 輸入 | ?-(+(+1*cos(x)))*cos((x-cos(x)))? |
| 我的輸出 | ?-(+(((+(((+0+(-1*sin(x)*1)*1))))))*cos((x-cos(x)))+(-1*sin((x-cos(x)))*((1--1*sin(x))))*(+(+1cos(x))))? |
| 錯誤原因 | ?我在處理連乘項的時候,用?replaceFirst("\\*", "");?取代第一個乘號,但第一項前面沒有*,所以替換了一二項間的*,導致出錯 |
| 解決方案 | 用?replaceALL("^\\*", "");?代替了上述代碼,解決問題 |
這個BUG屬于考慮不全面造成的錯誤,測試時也未覆蓋到(測試樣例太少,復雜測試樣例更少)。
?
(3)程序測試分析
測試方法:我用之前構造的測試樣例先大致測試一遍,在觀察一些易考察的部分(如:有無使用BigInteger包),進行針對性測試。
反思:全程手動,無自動化工具,所以效率不高,希望以后能學習使用自動化測試技術。
debug的部分情況如下:
| 輸入 | 輸出 | 原因 |
| ?13412312235423432? | ? WRONG FORMAT!? | ?沒用BigInteger |
| ? ---2 * x ? | ?2 | ---識別為+ |
| - x^+4*sin(x)^7+12*x^0001+ + +12*x-123- - x+12 | ??WRONG FORMAT!? | 無法識別+ + +12 |
| - x^+4*sin(x)^7+12*x^0001+ + +12*x-123- - x+12 | ?-((7*sin(x)^6*cos(x)*(+1))*1+0)*(x^4)+sin(x)^7*1*(4*x^3)+12+12-0+1+0? | 計算錯誤 |
| ((sin (x ^ +1) ^ +10000))? | ??WRONG FORMAT!? | +10000認為>10000? |
| ((sin (x ^ +1) ^ +10000)) | ??WRONG FORMAT!? | 中間tab無法識別? |
| ? ((sin (x ^ +1) ^ +10000)) | ?java報錯 | ?創建了0長度的BigInteger |
?
?
Applying Creational Pattern
第三次作業中用到了繼承,但是沒有對象構建的模式,仍舊是面向過程式的想用某個項時,特殊調用某個項。借鑒了各路大神的思路,有了初步的想法。通過一個工廠函數,將當前字符串輸入,返回一個對應類的對象。代碼如下:
1 public static Factor factorFactory(String str) { 2 if (str.contains("sin")) { 3 return new FactorSin(str); 4 } else if (str.contains("cos")) { 5 return new FactorCos(str); 6 } else { 7 return new FactorX(str); 8 } 9 }?
總結
1)面向對象的思維在三次作業中逐漸建立起來,但是代碼實際上還是面向過程,有待改進。
2)對于java一些包的使用不熟練,只會用幾個基本的包(BigInteger、ArrayList、StringBuilder等)。
3)優化太少,且多為面向數據的優化,很少建立優化規則。
4)手造測試數據太隨便,應該進行分模塊的覆蓋性測試。
5)代碼耦合度太高,需要解耦
6)好的構造思路遠比“打補丁”高效
?
希望多思考,多實踐,多看大佬分享的思路,OO加油啊~
?
轉載于:https://www.cnblogs.com/Guo-mengqi/p/10598929.html
總結
以上是生活随笔為你收集整理的OO第一单元总结__多项式求导问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 带偏移量的AES加密工具
- 下一篇: com.sun.jersey.api.c