OO面向對象課程做業1-3總結

做業1、多項式的加減運算

一、設計要點與自我分析

我設計的類圖
java

複雜度分析圖

正則表達式

老師建議類圖
算法

我設計了兩個類來進行多項式的計算,類Polynomial進行多項式的存儲和輸入輸出,第二個類進行多項式加減運算。而加減運算的類裏面只有方法,並且都是靜態方法,沒有存儲變量,感受這個設計仍是有些問題。以後我也參考了一下別人的代碼。編程

在Method Metrics中能夠看到ev, iv, v這三欄,分別代指基本複雜度(Essential Complexity (ev(G))、模塊設計複雜度(Module Design Complexity (iv(G)))、Cyclomatic Complexity (v(G))圈複雜度。
ev(G)基本複雜度是用來衡量程序非結構化程度的,非結構成分下降了程序的質量,增長了代碼的維護難度,使程序難於理解。所以,基本複雜度高意味着非結構化程度高,難以模塊化和維護。實際上,消除了一個錯誤有時會引發其餘的錯誤。
Iv(G)模塊設計複雜度是用來衡量模塊斷定結構,即模塊和其餘模塊的調用關係。軟件模塊設計複雜度高意味模塊耦合度高,這將致使模塊難於隔離、維護和複用。模塊設計複雜度是從模塊流程圖中移去那些不包含調用子模塊的斷定和循環結構後得出的圈複雜度,所以模塊設計複雜度不能大於圈複雜度,一般是遠小於圈複雜度。
v(G)是用來衡量一個模塊斷定結構的複雜程度,數量上表現爲獨立路徑的條數,即合理的預防錯誤所需測試的最少路徑條數,圈複雜度大說明程序代碼可能質量低且難於測試和維護,經驗代表,程序的可能錯誤和高的圈複雜度有着很大關係。
Class metrics中兩欄分別爲Ocavg(Average Operation Complexity)和WMC(Weighed method complexity)
在main函數中,個人基本複雜度較大較大,我定義了一個output的函數方法用於輸出結果,不過模塊化程度還算能夠。數組

  • 多項式的存儲:
    我用的是一維數組來存儲多項式,下標表明的是多項式的次數,數組存儲的是多項式的係數,這種存儲方法對於多項式加減法的操做很方便,可是浪費的空間大,由於不少係數是0;並且存儲多項式加減式子的時候也開了大數組將全部數據裝進去,一次性進行計算,這樣也浪費了大量的空間。
    參考了大佬的代碼,學習了一下如何管理多項式的存儲和加減:eclipse

    一、專門設出一個類來存多項式的每一項,包括係數和次數,而後開一個ArrayList<Object>來存儲這個類。模塊化

    二、加減法操做,將全部項加入到原來的ArrayList裏面,而後在ArrayList裏面對指數相同的項進行合併操做,再進行對指數從小到大的排序,用了sort()函數。函數

二、所用知識

1. 去除空白字符
s = s.replaceAll("\\s*", "");
2. 正則表達式的使用

一、使用group()捕獲組:學習

捕獲組是把多個字符當一個單獨單元進行處理的方法,它經過對括號內的字符分組來建立。group(0)表明的是整個匹配的表達式,以後每遇到一個左括號,group的索引值加一。測試

  • public String group( )

返回上次匹配操做(比方說find( ))的group 0(整個匹配)

  • public String group(int i)

返回上次匹配操做的某個group。若是匹配成功,可是沒能找到group,則返回null。

二、非貪婪匹配:

當「 ?」字符緊隨任何其餘限定符(*、+、?、{n}、{n,}、{n,m}以後時,匹配模式是"非貪心的"。"非貪心的"模式匹配搜索到的、儘量短的字符串,而默認的"貪心的"模式匹配搜索到的、儘量長的字符串。

*、+限定符都是貪婪的,由於它們會盡量多的匹配文字,只有在它們的後面加上一個?就能夠實現非貪婪或最小匹配。

三、判斷兩個字符串內容是否相等

須要用str.equals()的方法判斷,而不能使用「==」號。

四、錯誤的捕捉,使用try-catch和throw

try{
                ... ...
        }catch(IOException e){
            //處理IO異常的代碼
        }catch(NumberFormatException e){
            //處理parseInt不能轉換時的異常代碼
        }catch(StringIndexOutOfBoundsException e){
            //處理數組越界的異常代碼
        }catch(Exception e) {
            //總異常(父類)
        }

也能夠自定義異常,若是不知足某項條件則拋出異常

if(!m.find()){
    throw new PolynomialError();
}

五、結束進程
System.exit(0);

六、能夠重寫toString()的方法返回多項式的值。

三、碰見BUG以及改正方法

一、正則表達式太長,在數據壓力大的時候可能會爆棧
我將整個多項式加減法的式子用正則表達式一次性匹配檢查格式是否正確,但因爲表達式太長,數據壓力大而爆棧。應該逐個多項式進行匹配,逐個向後查找。

二、係數相加的時候容易超出範圍

使用java異常處理語句進行異常的捕捉

三、輸出多項式的時候沒有判斷是不是輸出第一個大括號,致使前面出現逗號。

加入第一次進入輸出循環的判斷。

四、在本題目的多項式匹配當中,可以使用 **(^|\\+|-)(\\{.*?\\})**來匹配其中加減的操做項。

可是若是兩個加減項之間出現了非法字符,正則表達式會自動跳過非法字符去匹配下一項,要怎麼解決這個問題呢?我想到三種方法:

(1)將匹配成功的字符串刪除之後,用^從頭開始匹配。代碼以下:

String pattern = "^(^|\\+|-)(\\{.*?\\})";
    Pattern r = Pattern.compile(pattern);       
    Matcher m = r.matcher(line); 
    while (m.find()) { 
        System.out.println("Found value: " + m.group()); 
        line = line.replace(m.group(),"");
        m = r.matcher(line); 
    }

(2)每次記錄匹配字符串的長度,而後依次累加,若是發現累加獲得的字符串長度和讀到的m.start(0)索引值不一致,則中間有非法字符。
(3)用region(start,end)重設m的範圍。

四、Eclipse的使用總結

1. 導入工程
  • 設置工做空間(Workspace)有明顯的層次結構。 項目在最頂級,項目裏頭能夠有文件和文件夾。插件能夠經過資源插件提供的API來管理工做空間的資源。

  • 首先打開eclipse軟件,找到左上角File而後點擊,而後咱們選擇Import,點擊Import

  • 點擊Import後,會彈出Import窗口,而後找到General,點擊General左邊小三角,而後選擇Existing Projects into Workspace

  • 有時候點導入文件會出現提示

    Project is not a Java project.

    有幾種狀況:

    • package名字不相符:右鍵項目->Build Path來更改source folder的設置

    • eclipse 工程沒有build path,則在項目.project文件中添加

<buildSpec>
    <buildCommand>
    <name>org.eclipse.jdt.core.javabuilder</name>
    <arguments>
    </arguments>
    </buildCommand>
    </buildSpec>
    <natures>
    <nature>org.eclipse.jdt.core.javanature</nature>
    </natures>
  • JDK版本不對: 項目右鍵 -->properties-->Java Build Path-->Libraries 而後將JDK換成你當前的JDK版本
二、修改字符集

默認狀況下 Eclipse 字符集爲 GBK,但如今不少項目採用的是 UTF-8,這是咱們就須要設置咱們的 Eclipse 開發環境字符集爲 UTF-8, 設置步驟以下:

在菜單欄選擇Window -> Preferences -> General -> Workspace -> Text file encoding ,在 Text file encoding 中點擊 Other,選擇 UTF-8。

三、調試快捷鍵

F11――進入DEBUG視圖

F5——進入:移動到下一個步驟,若是當前行有一個方法調用,該控件將會跳轉到被調用方法的第一行執行。

F6——跳出:移動到下一行。若是在當前行有方法調用,那麼會直接移動到下一行執行。不會進入被調用方法體裏面。

F7——返回:從當前方法中跳出,繼續往下執行。

F8——移動到下一個斷點處執行。

做業2、電梯的簡單調度

一、設計要點與自我分析

邏輯結構圖:

類圖:

設計建議類圖:

複雜度分析圖:

本次做業的設計要點是多個類進行協同,同時使用隊列進行調度。我將請求加入到請求隊列當中,由調度器從請求隊列中讀取請求對電梯類進行調度和操做,樓層類我沒有實際用上,這也是設計上的不均衡。其餘幾個類職責比較分明,調度邏輯清晰。
能夠看到個人RequestQueue類的複雜度較高,由於我在裏面大量用if語句來判斷出現的不一樣格式錯誤來輸出錯誤提示,致使複雜度升高。

二、所用知識

LinkedList的使用,因爲本電梯使用的是隊列的結構,使用了以下幾種方法:

(1)q.offer(e) 在鏈表尾部插入元素

(2)q.peek() 獲取第一個元素

(3)q.remove(e) 刪除一個元素

(4)q.poll(e) 查詢並移除第一個元素

(5)遍歷鏈表:

//for循環遍歷
for(int i = 0; i < linkedList.size(); i++){
    linkedList.get(i);
}
//Foreach遍歷
for(Integer i : linkedList);
//迭代器遍歷
Iterator<Integer> iterator = linkedList.iterator();
while(iterator.hasNext()){
    iterator.next();
}

可是迭代器遍歷和foreach遍歷的時候由於是動態刪除鏈表會發生線程錯誤,因此我用了for循環遍歷。

三、碰見BUG以及改正方法

我使用了LinkedList()來存儲請求,每次執行一次請求會遍歷鏈表看看有沒有同質請求,有的話進行刪除。可是刪除之後鏈表的總長度會改變,因此刪除之後要將索引值減一。在debug的過程當中找出了這個錯誤,後來在公測的時候順利經過了。

我測試的同窗沒有用正則表達式,所有用if-else判斷,程序容錯能力過差,致使公測所有沒有過。

做業3、具備捎帶功能的電梯調度

一、設計要點與自我分析

  • 提升資源利用率是調度算法設計的核心目標
  • 「順路捎帶」:在去響應一個請求的路途中能夠把資源共享給順路可完成的請求

類圖:

複雜度分析:

老師推薦設計:

在第二次做業的基礎上,我用Scheduler類繼承了Dispatcher類,建立了電梯移動的接口。
我順路捎帶的思路是找到主請求,而後遍歷隊列後面能夠被捎帶的請求,找到離主請求最近的請求執行,若超出主請求的執行時間,便執行主請求,而後選擇捎帶的第一條消息做爲主請求。可是這個設計思路遇到了不少問題,後來參考了別人的思路。能夠將每次所能找到捎帶方向上的最高樓層做爲目標樓層,而後停靠中間的樓層,這樣的思路簡潔清晰,也省去了不少判斷的步驟。
能夠看到個人Scheduler類複雜度十分高,由於我思路的問題,致使在這個類裏面有不少判斷條件的語句,整個程序十分冗雜。

二、所用知識

(1)類的繼承
使用繼承機制,增長一個子類來重寫第二次做業中的schedule方法,須要注意子類不能繼承父類的構造器,可是父類的構造器帶有參數的,則必須在子類的構造器中顯式地經過super關鍵字調用父類的構造器並配以適當的參數列表。 若是父類有無參構造器,則在子類的構造器中用super調用父類構造器不是必須的,若是沒有使用super關鍵字,系統會自動調用父類的無參構造器。
(2)使用interface來概括電梯的運動方法。
(3)重寫toString()方法來得到電梯運行狀態和時刻的觀察。

三、碰見BUG以及改正方法

在此次的做業中,因爲我每次都是找到可捎帶請求的最小請求,可是在主請求更換的時候,我將主請求設爲了可捎帶的最小請求,而可捎帶的最小請求在前一條捎帶請求的後面發出,這就形成了後發出的指令先執行了。參考了其餘同窗的捎帶思路,即找到當前方向上可捎帶的最高樓層進行停靠,能夠簡化此問題。
其次就是輸出錯誤格式的問題,INVALID的輸出的是原請求,而我將請求的括號換掉了,致使不少bug。

測試策略

一開始我是根據錯誤分支樹來構造測試用例,後來的做業中,我根據別人的代碼結構來構造測試用例,發現代碼中的邏輯錯誤和bug。

心得體會

做爲剛接觸面向對象的小白,第一次做業佈置下來,就開始兩天速成Java,正則表達式,不少資料看得一臉懵逼,期間老是去打擾大佬,問一些十分基礎的問題。但在後面兩次做業中,對整個編寫流程開始熟練起來,也開始理解面向對象的編程思想。每次做業作完之後,也會參考一下別人的代碼,和本身的作一下對比,看看那些地方能更加簡潔的表達,更高效的處理,同時也感謝能將代碼分享給個人同窗~ 還有就是必定要仔細閱讀指導書,我就是由於指導書沒有好好看,致使程序出了不少bug,第一次做業因爲輸出提示沒有#提示,掛滿了錯誤分支樹,能夠說仍是很絕望的。第三次的指導書和第二次的差很少,我又很粗淺地看了,差點漏掉了重要信息,第一條指令有限制。後來是在看討論區的討論才發現了這個問題。 前期的邏輯結構設計必定要清晰,不然無腦開始寫代碼真的會遇到特別多問題。 轉系以後感受本身真的特別菜,改bug常常改到絕望,但仍是真心感謝一些可以和我交流的小夥伴。

相關文章
相關標籤/搜索