第一单元总结
一、作業(yè)分析
第一次作業(yè)
與后兩次作業(yè)相比,第一次作業(yè)非常簡單,僅要求對(duì)由常數(shù)項(xiàng)和冪函數(shù)組成的多項(xiàng)式求導(dǎo)。但由于缺少面向?qū)ο缶幊探?jīng)驗(yàn),我在這次作業(yè)中栽了不少跟頭。
(1)度量分析
在第一次作業(yè)中,我還沒有適應(yīng)JAVA語言面向?qū)ο蟮腸oding風(fēng)格。可以看到,我的第一次作業(yè)只有一個(gè)主類One,所有方法都堆在一個(gè)類中。這也導(dǎo)致了我的程序的各類復(fù)雜度都相當(dāng)爆炸,總之是一次慘痛的教訓(xùn)。
(2)bug分析
首先,最重要的一點(diǎn):
不要特判!!
不要特判!!
不要特判!!
由于寒假摸魚的緣故,我對(duì)JAVA的很多功能都不甚了解,這個(gè)問題在這次作業(yè)中充分暴露出來了。
String matchB =str.replaceAll("[\\t ]*[\\+-][\\t ]*[\\+-][\\t ]+\\d", "w");matchB = matchB.replaceAll("[\\+-][\\t ]*[\\+-][\\t ]*[\\+-]", "w");matchB = matchB.replaceAll("\\d[\\t ]*x", "w");matchB = matchB.replaceAll("x[\\t ]*\\d", "w");matchB = matchB.replaceAll("\\^[\\t ]*[\\+-][\\t ]*[\\+-]", "w");matchB = matchB.replaceAll("\\d[\\t ]+\\d", "w");matchB = matchB.replaceAll("[\\+-][\\t ]*\\*", "w");matchB = matchB.replaceAll("x[\\t ]*\\*", "w");matchB = matchB.replaceAll("(xx)|(\\^[ \\t]*x)", "w");matchB = matchB.replaceAll("\\^[ \\t]*[\\+-][ \\t]+\\d", "w");matchB = matchB.replaceAll("\\^[ \\t]*[+-]*[ \\t]*\\d*\\*", "w");matchB = matchB.replaceAll("[\\t ]", "");if (matchB.length() == 0) {matchB = "w";}String matchC = matchB.replaceAll("\\*x\\^", "");String matchD = matchC.replaceAll("\\d\\*x", "1");String matchE = matchD.replaceAll("[\\+-][\\+-]?(\\d|(x\\^?))", "");matchE = matchE.replaceAll("x\\^?", "");
這是我第一次作業(yè)checkstyle部分的代碼,當(dāng)時(shí)我還不能熟練使用正則表達(dá)式來檢查代碼格式。
特判最大的弊端就是對(duì)編程者提取錯(cuò)誤信息的能力提出了很高要求,一旦編程者考慮的錯(cuò)誤情況不全,就極易在檢查格式這一步上栽跟頭。?
此外,由于第一次作業(yè)中采用了樸素的特判處理作為checkstyle的方法,我的這一次作業(yè)程序的擴(kuò)展性極差,第二次作業(yè)只能推倒重來,這也需要引以為戒。
? 第二次作業(yè)
第二次作業(yè)的內(nèi)容是對(duì)包含簡單冪函數(shù)和簡單正余弦函數(shù)的導(dǎo)函數(shù)的求解,在這次作業(yè)中,我將上一次作業(yè)的代碼推倒重建,代碼風(fēng)格開始逐漸偏向面向?qū)ο蠖皇敲嫦蜻^程。
(1)度量分析
在第二次作業(yè)中,我開始嘗試使用多個(gè)類處理不同任務(wù),但是有部分類依舊顯得過于臃腫。這是我還沒有面向?qū)ο蠡捏w現(xiàn)。
我的整體思路是在CheckStyle類中完成格式檢查,在Poly類中完成求導(dǎo)計(jì)算和輸出,Main類的功能則是整體調(diào)度。可以發(fā)現(xiàn),我的思路依舊是將類作為一個(gè)大型函數(shù)來使用,其本質(zhì)還是面向過程而非面向?qū)ο蟆8鱾€(gè)部分也沒有做到高度分工,尤其是Poly類,同時(shí)需要完成求導(dǎo)計(jì)算、化簡和輸出這三個(gè)任務(wù)。這也導(dǎo)致了Poly類的復(fù)雜度特別大。
(2)bug分析
我吸取了第一次作業(yè)的教訓(xùn),采用了正則表達(dá)式作為checkstyle的工具,在提取項(xiàng)的過程中也將正則表達(dá)式作為搜索關(guān)鍵詞使用。
Pattern p = Pattern.compile("^[ \\t]*[+-]?[ \\t]*[+-]?[ \\t]*" +"((([+-]?\\d+)|(x([ \\t]*+\\^[ \\t]*[+-]?\\d+)?)" +"|(sin[ \\t]*\\([ \\t]*x[ \\t]*\\)" +"([ \\t]*\\^[ \\t]*[+-]?\\d+)?)" +"|(cos[ \\t]*\\([ \\t]*x[ \\t]*\\)" +"([ \\t]*\\^[ \\t]*[+-]?\\d+)?))" +"([ \\t]*\\*[ \\t]*(([+-]?\\d+)" +"|([ \\t]*x([ \\t]*\\^[ \\t]*[+-]?\\d+)?)" +"|([ \\t]*sin[ \\t]*\\([ \\t]*x[ \\t]*\\)" +"([ \\t]*\\^[ \\t]*[+-]?\\d+)?)" +"|([ \\t]*cos[ \\t]*\\([ \\t]*x[ \\t]*\\)" +"([ \\t]*\\^[ \\t]*[+-]?\\d+)?)))*)" +"([ \\t]*[+-][ \\t]*[+-]?[ \\t]*" +"((([+-]?\\d+)|(x([ \\t]*\\^[ \\t]*[+-]?\\d+)?)" +"|(sin[ \\t]*\\([ \\t]*x[ \\t]*\\)" +"([ \\t]*\\^[ \\t]*[+-]?\\d+)?)" +"|(cos[ \\t]*\\([ \\t]*x[ \\t]*\\)" +"([ \\t]*\\^[ \\t]*[+-]?\\d+)?))" +"([ \\t]*\\*[ \\t]*(([+-]?\\d+)" +"|([ \\t]*x([ \\t]*\\^[ \\t]*[+-]?\\d+)?)" +"|([ \\t]*sin[ \\t]*\\([ \\t]*x[ \\t]*\\)" +"([ \\t]*\\^[ \\t]*[+-]?\\d+)?)" +"|([ \\t]*cos[ \\t]*\\([ \\t]*x[ \\t]*\\)" +"([ \\t]*\\^[ \\t]*[+-]?\\d+)?)))*))*+[ \\t]*$");這是我checkstyle時(shí)使用的超大正則,經(jīng)過實(shí)際檢驗(yàn)并不會(huì)爆棧。大正則的好處是比較直觀,缺點(diǎn)則是編寫和debug時(shí)會(huì)比較痛苦,只能說要慎用。
?
private String strin;private Map<String,String> match = new HashMap<String,String>();private Map<String,String> result = new HashMap<String,String>();我新建了兩個(gè)hashmap變量用來保存項(xiàng)的內(nèi)容,第一個(gè)保存求導(dǎo)前的內(nèi)容,第二個(gè)保存求導(dǎo)結(jié)果。這樣做的好處是便于合并同類項(xiàng),可以把項(xiàng)的內(nèi)容作為保存的關(guān)鍵詞,項(xiàng)的系數(shù)作為保存的內(nèi)容。
我的這次作業(yè)中并沒有出現(xiàn)bug,但由于我未考慮諸如sin(x)^2+cos(x)^2這類情況的化簡,導(dǎo)致我的性能分比較低。
第三次作業(yè)
第三次作業(yè)在前兩次作業(yè)的基礎(chǔ)上加入了嵌套函數(shù)的定義,盡管這類嵌套僅限定在正余弦函數(shù)中,但這仍給編程帶來了相當(dāng)大的挑戰(zhàn)。
(1)度量分析
在這次作業(yè)中,我使用CheckStyle類檢查代碼格式,Calculator類完成求導(dǎo)計(jì)算,Print類完成化簡和輸出,Poly類作為存儲(chǔ),Main類整體調(diào)度。可以看到,代碼復(fù)雜度相較前兩次有了明顯降低。部分類的復(fù)雜度較高的原因可能是我定義了比較多的正則表達(dá)式變量的原因。
(2)bug分析
我這次作業(yè)的bug主要來自于正則表達(dá)式的編寫錯(cuò)誤。由于本次作業(yè)的結(jié)構(gòu)與之前有較大差異,我重構(gòu)了之前的正則表達(dá)式,不慎有一處括號(hào)寫錯(cuò)了地方,導(dǎo)致在checkstyle部分產(chǎn)生了很嚴(yán)重的誤判。
二、debug經(jīng)驗(yàn)
我debug的主要方法還是人工查bug(不會(huì)寫評(píng)測機(jī)的淚),效率很低,但對(duì)我個(gè)人編程能力有很大的提升。尤其是在閱讀代碼風(fēng)格很好的代碼時(shí),會(huì)讓人有眼前一亮的感覺。
我習(xí)慣先順著別人的思路將他的程序按流程過一遍,從而分析他的程序在哪一步可能會(huì)出問題。這種方法對(duì)于找bug而言效率很低,但是在閱讀學(xué)習(xí)他人程序時(shí)可以排上用場,靠人眼評(píng)測機(jī)來理解作者想要表達(dá)的意圖,并將其1轉(zhuǎn)化為自己的知識(shí)。
三、反思
第一單元的三次作業(yè),主要目的是給我們“練手”,逐漸培養(yǎng)面向?qū)ο蟮木幊田L(fēng)格。因此,模塊化編程就十分重要了,我現(xiàn)在習(xí)慣在coding前先理一遍整體思路,將各個(gè)部分需要實(shí)現(xiàn)的功能規(guī)劃清楚,在一步步完善各個(gè)部分,最后將這些部件“組裝”成一個(gè)完整的程序。
轉(zhuǎn)載于:https://www.cnblogs.com/DoubleRider/p/10609120.html
總結(jié)
- 上一篇: 解决设置了display:none的元素
- 下一篇: Koa 中间件的执行