1. 程式人生 > 其它 >OO2022第一單元總結

OO2022第一單元總結

OO2022第一單元總結

第一單元內容是表示式化簡,有一定的難度。三次作業迭代實現更多的功能。就個人而言,三次作業都延用了Parse->Simplify的流程,解析部分借用了編譯中詞法分析和語法分析的思想。簡化部分分為拆括號和合並(不嚴格分開,可能為了效能交錯進行)兩部分。

在第二次作業出現了較大的問題,導致強測WA了很多點。第三次作業進行了重構,效果比較好。

第一次作業

概述

第一次作業較為簡單,不難分析得出所有項都可以化成a*x**b的形式,這為合併帶來了很大的簡化(也為第二次架構崩壞埋下了伏筆)。

UML

classDiagram class Parser{ -expr: Expr -pos: int -exprFactor() ExprFactor +parse() boolean -expr() Expr -number() BigInteger -constFactor() ConstFactor -advance() void -varFactor() VarFactor -term() Term -peek() Token -consume(TokenType) void +getExpr() Expr -isAtEnd() boolean +getPos() int } class Simplifier{ -simplifyTerm(Term) ArrayList~BasicTerm~ +simplify(Expr) ArrayList~BasicTerm~ -simplifyFactor(ExprNode) ArrayList~BasicTerm~ -simplifyExpr(Expr) ArrayList~BasicTerm~ } class BasicTerm{ -fac: BigInteger -idx: BigInteger +getFac() BigInteger +getIdx() BigInteger +mul(BasicTerm) BasicTerm +toString() String +add(BasicTerm) BasicTerm +negate() BasicTerm +printExpr(ArrayList~BasicTerm~) void +multiply(ArrayList~BasicTerm~,ArrayList~BasicTerm~) ArrayList~BasicTerm~ +negateAll(ArrayList~BasicTerm~) ArrayList~BasicTerm~ +merge(ArrayList~BasicTerm~) ArrayList~BasicTerm~ } class ExprNode{ << interface >> } class ExprFactor{ -pow: BigInteger -expr: Expr +toString() String +getExpr() Expr +getPow() BigInteger } class Expr{ -terms: ArrayList~Term~ -prefixOperators: ArrayList~TokenType~ +toString() String +getTerms() ArrayList~Term~ +getPrefixOperators() ArrayList~TokenType~ } class ConstFactor{ -value: BigInteger +toString() String +getValue() BigInteger } class VarFactor{ -pow: BigInteger +toString() String +getPow() BigInteger } class Term{ -prefixOperator: TokenType -exprNodes: ArrayList~ExprNode~ +toString() String +getPrefixOperator() TokenType +getExprNodes() ArrayList~ExprNode~ } class Tokenizer{ -tokens: ArrayList~Token~ -peek2() Character -advance() void -number() void -peek() Character +run() boolean -isAtEnd() boolean +getTokens() ArrayList~Token~ } class Token{ -number: BigInteger -type: TokenType -symbol: String +toString() String +getType() TokenType +getSymbol() String +getNumber() BigInteger } class TokenType{ << enumeration>> Add Number SStar Star Sub Symbol LParen RParen } ExprFactor ..|> ExprNode Expr ..|> ExprNode ConstFactor ..|> ExprNode VarFactor ..|> ExprNode Term ..|> ExprNode VarFactor --* Term ConstFactor --* Term Term --* Expr Token *-- TokenType Tokenizer ..> Token Parser ..> Token Simplifier ..> BasicTerm Parser ..> ExprNode Simplifier ..> ExprNode

分析

input expr --Tokenizer--> Token --Parser--> ExprNode(AST) --Simplifier--> BasicTerm --> output expr

如上將表示式化簡的任務劃分到Tokenizer詞法分析器,Parser語法分析器,Simplifier簡化器,實現功能解耦。而TokenASTBasicTerm 在上述類組成的流水線中最終處理得到簡化的表示式。

就後兩次作業的情況這種抽象方式擴充套件性尚可,詞法分析器器和語法分析器與簡化過程解耦,在第一次和第二次作業只做了少量修改,在第二次到第三次作業沒有進行任何修改(因為使用遞迴下降法,所以其實在第一次作業就是支援多層巢狀的)。而簡化部分由於第二次作業設計失誤在第三次進行了很多重構。

使用不可變的物件是減少bug的一種有效方法。在第一次作業中,TokenExprNodeBasicTerm都是不可變的(在第三次作業開了可變的口子就出現了和深複製相關的奇怪的bug)。

在設計Token的表示形式的時候是在模擬C的tagged union。

struct Token{
    enum TokenType type;
    union{
        char* str;
        int num;
    }data;
}

大概是這種形式,感覺不是非常的面向物件,但是如果實現一堆繼承Token的子類又會過度抽象。

在對錶達式樹進行建模的時候使用了繼承多型,工具報了一堆Unutilized Abstraction

可能還是我的建模不是很合理,應該尋找表示式樹每一個層級的共性抽取一個父類(如都存在一個方法化簡自己),而且Simplifier類裡用一系列靜態方法進行化簡也不是很好。

度量值

Project Name ,Package Name      ,Type Name   ,MethodName         ,LOC ,CC ,PC
proj1        ,(default package) ,BasicTerm   ,getFac             ,3   ,1  ,0
proj1        ,(default package) ,BasicTerm   ,getIdx             ,3   ,1  ,0
proj1        ,(default package) ,BasicTerm   ,BasicTerm          ,4   ,1  ,2
proj1        ,(default package) ,BasicTerm   ,BasicTerm          ,4   ,1  ,0
proj1        ,(default package) ,BasicTerm   ,mul                ,3   ,1  ,1
proj1        ,(default package) ,BasicTerm   ,add                ,3   ,1  ,1
proj1        ,(default package) ,BasicTerm   ,negate             ,3   ,1  ,0
proj1        ,(default package) ,BasicTerm   ,merge              ,18  ,5  ,1
proj1        ,(default package) ,BasicTerm   ,multiply           ,9   ,3  ,2
proj1        ,(default package) ,BasicTerm   ,negateAll          ,6   ,2  ,1
proj1        ,(default package) ,BasicTerm   ,toString           ,25  ,7  ,0
proj1        ,(default package) ,BasicTerm   ,printExpr          ,14  ,4  ,1
proj1        ,(default package) ,ExprNode    ,getPow             ,3   ,1  ,0
proj1        ,(default package) ,ExprNode    ,VarFactor          ,3   ,1  ,1
proj1        ,(default package) ,ExprNode    ,toString           ,3   ,1  ,0
proj1        ,(default package) ,ExprNode    ,getValue           ,3   ,1  ,0
proj1        ,(default package) ,ExprNode    ,ConstFactor        ,3   ,1  ,1
proj1        ,(default package) ,ExprNode    ,toString           ,3   ,1  ,0
proj1        ,(default package) ,ExprNode    ,getPow             ,3   ,1  ,0
proj1        ,(default package) ,ExprNode    ,getExpr            ,3   ,1  ,0
proj1        ,(default package) ,ExprNode    ,ExprFactor         ,4   ,1  ,2
proj1        ,(default package) ,ExprNode    ,toString           ,3   ,1  ,0
proj1        ,(default package) ,ExprNode    ,Term               ,4   ,1  ,2
proj1        ,(default package) ,ExprNode    ,getExprNodes       ,3   ,1  ,0
proj1        ,(default package) ,ExprNode    ,getPrefixOperator  ,3   ,1  ,0
proj1        ,(default package) ,ExprNode    ,toString           ,3   ,1  ,0
proj1        ,(default package) ,ExprNode    ,getTerms           ,3   ,1  ,0
proj1        ,(default package) ,ExprNode    ,getPrefixOperators ,3   ,1  ,0
proj1        ,(default package) ,ExprNode    ,Expr               ,4   ,1  ,2
proj1        ,(default package) ,ExprNode    ,toString           ,3   ,1  ,0
proj1        ,(default package) ,VarFactor   ,getPow             ,3   ,1  ,0
proj1        ,(default package) ,VarFactor   ,VarFactor          ,3   ,1  ,1
proj1        ,(default package) ,VarFactor   ,toString           ,3   ,1  ,0
proj1        ,(default package) ,ConstFactor ,getValue           ,3   ,1  ,0
proj1        ,(default package) ,ConstFactor ,ConstFactor        ,3   ,1  ,1
proj1        ,(default package) ,ConstFactor ,toString           ,3   ,1  ,0
proj1        ,(default package) ,ExprFactor  ,getPow             ,3   ,1  ,0
proj1        ,(default package) ,ExprFactor  ,getExpr            ,3   ,1  ,0
proj1        ,(default package) ,ExprFactor  ,ExprFactor         ,4   ,1  ,2
proj1        ,(default package) ,ExprFactor  ,toString           ,3   ,1  ,0
proj1        ,(default package) ,Term        ,Term               ,4   ,1  ,2
proj1        ,(default package) ,Term        ,getExprNodes       ,3   ,1  ,0
proj1        ,(default package) ,Term        ,getPrefixOperator  ,3   ,1  ,0
proj1        ,(default package) ,Term        ,toString           ,3   ,1  ,0
proj1        ,(default package) ,Expr        ,getTerms           ,3   ,1  ,0
proj1        ,(default package) ,Expr        ,getPrefixOperators ,3   ,1  ,0
proj1        ,(default package) ,Expr        ,Expr               ,4   ,1  ,2
proj1        ,(default package) ,Expr        ,toString           ,3   ,1  ,0
proj1        ,(default package) ,Main        ,main               ,9   ,1  ,1
proj1        ,(default package) ,Parser      ,getPos             ,3   ,1  ,0
proj1        ,(default package) ,Parser      ,getExpr            ,3   ,1  ,0
proj1        ,(default package) ,Parser      ,Parser             ,6   ,1  ,1
proj1        ,(default package) ,Parser      ,parse              ,4   ,1  ,0
proj1        ,(default package) ,Parser      ,expr               ,19  ,4  ,0
proj1        ,(default package) ,Parser      ,term               ,42  ,11 ,0
proj1        ,(default package) ,Parser      ,varFactor          ,12  ,3  ,0
proj1        ,(default package) ,Parser      ,number             ,24  ,5  ,0
proj1        ,(default package) ,Parser      ,constFactor        ,4   ,1  ,0
proj1        ,(default package) ,Parser      ,exprFactor         ,20  ,4  ,0
proj1        ,(default package) ,Parser      ,isAtEnd            ,3   ,1  ,0
proj1        ,(default package) ,Parser      ,peek               ,3   ,1  ,0
proj1        ,(default package) ,Parser      ,advance            ,3   ,1  ,0
proj1        ,(default package) ,Parser      ,consume            ,9   ,2  ,1
proj1        ,(default package) ,Simplifier  ,simplify           ,3   ,1  ,1
proj1        ,(default package) ,Simplifier  ,simplifyExpr       ,13  ,3  ,1
proj1        ,(default package) ,Simplifier  ,simplifyTerm       ,11  ,3  ,1
proj1        ,(default package) ,Simplifier  ,simplifyFactor     ,24  ,5  ,1
proj1        ,(default package) ,Token       ,Token              ,5   ,1  ,3
proj1        ,(default package) ,Token       ,getSymbol          ,3   ,1  ,0
proj1        ,(default package) ,Token       ,getNumber          ,3   ,1  ,0
proj1        ,(default package) ,Token       ,getType            ,3   ,1  ,0
proj1        ,(default package) ,Token       ,toString           ,10  ,3  ,0
proj1        ,(default package) ,Tokenizer   ,Tokenizer          ,6   ,1  ,1
proj1        ,(default package) ,Tokenizer   ,getTokens          ,3   ,1  ,0
proj1        ,(default package) ,Tokenizer   ,run                ,48  ,12 ,0
proj1        ,(default package) ,Tokenizer   ,number             ,17  ,3  ,0
proj1        ,(default package) ,Tokenizer   ,peek               ,8   ,2  ,0
proj1        ,(default package) ,Tokenizer   ,peek2              ,8   ,2  ,0
proj1        ,(default package) ,Tokenizer   ,advance            ,3   ,1  ,0
proj1        ,(default package) ,Tokenizer   ,isAtEnd            ,3   ,1  ,0

Project Name ,Package Name      ,Type Name   ,NOF ,NOPF ,NOM ,NOPM ,LOC ,WMC ,NC ,DIT ,LCOM                ,FANIN ,FANOUT
proj1        ,(default package) ,BasicTerm   ,2   ,0    ,12  ,12   ,99  ,28  ,0  ,0   ,0.16666666666666666 ,0     ,0
proj1        ,(default package) ,ExprNode    ,8   ,0    ,18  ,18   ,77  ,18  ,0  ,0   ,0.2222222222222222  ,0     ,0
proj1        ,(default package) ,VarFactor   ,1   ,0    ,3   ,3    ,12  ,3   ,0  ,0   ,0.0                 ,0     ,0
proj1        ,(default package) ,ConstFactor ,1   ,0    ,3   ,3    ,12  ,3   ,0  ,0   ,0.0                 ,0     ,0
proj1        ,(default package) ,ExprFactor  ,2   ,0    ,4   ,4    ,17  ,4   ,0  ,0   ,0.0                 ,0     ,0
proj1        ,(default package) ,Term        ,2   ,0    ,4   ,4    ,17  ,4   ,0  ,0   ,0.0                 ,0     ,0
proj1        ,(default package) ,Expr        ,2   ,0    ,4   ,4    ,17  ,4   ,0  ,0   ,0.0                 ,0     ,0
proj1        ,(default package) ,Main        ,0   ,0    ,1   ,1    ,11  ,1   ,0  ,0   ,-1.0                ,0     ,0
proj1        ,(default package) ,Parser      ,4   ,0    ,14  ,4    ,161 ,37  ,0  ,0   ,0.21428571428571427 ,0     ,0
proj1        ,(default package) ,Simplifier  ,0   ,0    ,4   ,1    ,53  ,12  ,0  ,0   ,-1.0                ,0     ,0
proj1        ,(default package) ,Token       ,3   ,0    ,5   ,5    ,29  ,7   ,0  ,0   ,0.0                 ,0     ,0
proj1        ,(default package) ,Tokenizer   ,4   ,0    ,8   ,3    ,102 ,23  ,0  ,0   ,0.0                 ,0     ,0

詞法和語法分析存在CC圈複雜度較高的問題(都是固定寫法,雖然邏輯較為複雜但是讀起來還是比較清晰),其他部分複雜度尚可,BasicTerm內聚缺乏度較高(第二次作業崩掉的禍根之一)。

Bug

本次作業Bug較少,只發現了一個爆Long的錯誤,改成BigInteger就對了。第一次作業比較簡單,在同學們熱情的hack下應該不會潛藏什麼Bug?

第二次作業

概述

第二次作業屬於是迭代開發失敗。強行用第一次作業的架構增加第二次作業的功能,比如第一次對基本項a*x**b的抽象已經不是很適用了,我卻根據資料限制的巢狀層數條件在上面打補丁,導致最終BasicTerm顯得不倫不類。還在解析表示式樹的程式碼中加入了很多資料限制相關的特判,導致複雜度加大,難以維護。

其實本來就採用了遞迴的方法,就應該直接用第三次作業取消巢狀限制後的寫法,這樣程式碼結構還會更加統一。

UML

classDiagram class Parser{ -expr: Expr -pos: int -exprFactor() ExprFactor +parse() boolean +parseCustomFunction() boolean -funCallFactor() FunCallFactor -expr() Expr -number() BigInteger -constFactor() ConstFactor -advance() void -varFactor() VarFactor -term() Term -peek() Token -consume(TokenType) void +getExpr() Expr -isAtEnd() boolean +getPos() int } class Simplifier{ -simplifyTerm(Term,HashMap~String,ExprNode~) ArrayList~BasicTerm~ +simplify(Expr) ArrayList~BasicTerm~ -simplifyFactor(ExprNode,HashMap~String,ExprNode~) ArrayList~BasicTerm~ +simplifyExpr(Expr,HashMap~String,ExprNode~) ArrayList~BasicTerm~ -simplifyFactor(ExprNode,HashMap~String,ExprNode~) ArrayList~BasicTerm~ -dispatchTriangleFunctions(ArrayList~BasicTerm~,FunCallFactor, HashMap~String,ExprNode~) -dispatchCos(ArrayList~BasicTerm~,FunCallFactor, HashMap~String,ExprNode~) -dispatchSin(ArrayList~BasicTerm~,FunCallFactor, HashMap~String,ExprNode~) -dispatchFunctions(ExprNode,ArrayList~BasicTerm~,FunCallFactor, HashMap~String,ExprNode~) } class BasicTerm{ -basicFactors: ArrayList~BasicFactor~ -fac: BigInteger +add(BasicTerm) Term +extractFactor() void +toString() String +merge(ArrayList~BasicTerm~) ArrayList~BasicTerm~ +multiply(ArrayList~BasicTerm~,ArrayList~BasicTerm~) ArrayList~BasicTerm~ +printExpr(ArrayList~BasicTerm~) void +negateAll(ArrayList~BasicTerm~) ArrayList~BasicTerm~ +mul(BasicTerm) BasicTerm +negate() BasicTerm +getFac() BigInteger +getBasicFactors() ArrayList~BasicFactor~ } class BasicFactor{ -fac: BigInteger -idx: BigInteger -idxInner: BigInteger -facInner: BigInteger -factorType: FactorType +getFac() BigInteger +getIdx() BigInteger +setFac(BigInteger) +setIdx(BigInteger) -isTriangleOne() boolean -isTriangleZero() boolean +getFactorType() FactorType +getFacInner() BigInteger +getIdxInner() BigInteger -getFactorString(BigInteger,BigInteger,String) String +createCos(BigInteger,BigInteger,BigInteger,BigInteger) BasicFactor +canMerge(BasicFactor,BasicFactor) boolean +toString() String +merge(ArrayList~BasicFactor~) ArrayList~BasicFactor~ +createSin(BigInteger,BigInteger,BigInteger,BigInteger) BasicFactor +createX(BigInteger,BigInteger) BasicFactor } class ExprNode{ << interface >> +wrapNode(ExprNode) Expr } class ExprFactor{ -pow: BigInteger -expr: Expr +toString() String +getExpr() Expr +getPow() BigInteger } class Expr{ -terms: ArrayList~Term~ -prefixOperators: ArrayList~TokenType~ +toString() String +getTerms() ArrayList~Term~ +getPrefixOperators() ArrayList~TokenType~ } class ConstFactor{ -value: BigInteger +toString() String +getValue() BigInteger } class VarFactor{ -pow: BigInteger +toString() String +getPow() BigInteger } class Term{ -prefixOperator: TokenType -exprNodes: ArrayList~ExprNode~ +toString() String +getPrefixOperator() TokenType +getExprNodes() ArrayList~ExprNode~ } class FunCallFactor{ -symbol: String -paraList: ArrayList<ExprNode> -pow: BigInteger +getSymbol() String +getPow() BigInteger +getParaList() ArrayList~ExprNode~ } class Tokenizer{ -tokens: ArrayList~Token~ -peek2() Character -advance() void -number() void -peek() Character +run() boolean -isAtEnd() boolean +getTokens() ArrayList~Token~ -identifier() void } class Token{ -number: BigInteger -type: TokenType -symbol: String +toString() String +getType() TokenType +getSymbol() String +getNumber() BigInteger } class TokenType{ << enumeration>> Add Number SStar Star Sub Symbol LParen RParen Comma Equal } class CustomFunction{ -paraList: ArrayList~String~ -body: ExprNode +eval(ArrayList~ExprNode~) ArrayList~BasicTerm~ } class Klone~T~{ << interface >> klone() T } class Comparable~T~{ << interface >> } class FactorType{ << enumeration >> X Sin Cos } ExprFactor ..|> ExprNode Expr ..|> ExprNode ConstFactor ..|> ExprNode VarFactor ..|> ExprNode Term ..|> ExprNode FunCallFactor --* Term VarFactor --* Term ConstFactor --* Term ExprFactor --* Term Term --* Expr Token *-- TokenType Tokenizer ..> Token Parser ..> Token Simplifier ..> BasicTerm Parser ..> ExprNode Simplifier ..> ExprNode Simplifier ..> CustomFunction BasicFactor ..|> Klone BasicTerm ..|> Klone ExprNode ..|> Klone BasicFactor --* BasicTerm FactorType --* BasicFactor BasicFactor ..|> Comparable

分析

方法上和第一次作業基本相同,但是由於加入了三角函式,項不能統一成a*x**b的結構了,但是由於資料限制,三角函式裡只能有冪函式因子,而且只能有一層,於是直接將其硬寫進BasicFactor,這就是facInneridxInner兩個奇怪的資料的由來(最後還是不得不重構)。而由於使用ArrayList儲存因子和項,為了判斷”可以合併“,需要一種”標準形式”,於是想到進行排序並提取項的係數部分,讓其變為fac * (1*x**b) * (1*x**c) ....的形式(中間不一定是x,也可能是三角函式)。

可以看出上述方法依賴於資料限制,可想而知有很多特判,複雜度很高。

同時,程式碼中用ArrayList<BasicTerm>建模表達式,這顯然不符合封裝規則,也確實給我的編碼帶來了大量的麻煩,在第三次作業進行了重構。

度量值

Project Name ,Package Name      ,Type Name      ,MethodName                ,LOC ,CC ,PC
proj2        ,(default package) ,BasicFactor    ,BasicFactor               ,7   ,1  ,5
proj2        ,(default package) ,BasicFactor    ,createX                   ,3   ,1  ,2
proj2        ,(default package) ,BasicFactor    ,createCos                 ,3   ,1  ,4
proj2        ,(default package) ,BasicFactor    ,createSin                 ,3   ,1  ,4
proj2        ,(default package) ,BasicFactor    ,merge                     ,30  ,7  ,1
proj2        ,(default package) ,BasicFactor    ,isTriangleZero            ,3   ,1  ,0
proj2        ,(default package) ,BasicFactor    ,isTriangleOne             ,3   ,1  ,0
proj2        ,(default package) ,BasicFactor    ,canMerge                  ,3   ,1  ,2
proj2        ,(default package) ,BasicFactor    ,equalsAll                 ,11  ,4  ,2
proj2        ,(default package) ,BasicFactor    ,getFactorString           ,25  ,7  ,3
proj2        ,(default package) ,BasicFactor    ,klone                     ,3   ,1  ,0
proj2        ,(default package) ,BasicFactor    ,getFactorType             ,3   ,1  ,0
proj2        ,(default package) ,BasicFactor    ,getFacInner               ,3   ,1  ,0
proj2        ,(default package) ,BasicFactor    ,getIdxInner               ,3   ,1  ,0
proj2        ,(default package) ,BasicFactor    ,getFac                    ,3   ,1  ,0
proj2        ,(default package) ,BasicFactor    ,setFac                    ,3   ,1  ,1
proj2        ,(default package) ,BasicFactor    ,getIdx                    ,3   ,1  ,0
proj2        ,(default package) ,BasicFactor    ,setIdx                    ,3   ,1  ,1
proj2        ,(default package) ,BasicFactor    ,compareTo                 ,33  ,7  ,1
proj2        ,(default package) ,BasicFactor    ,equals                    ,10  ,3  ,1
proj2        ,(default package) ,BasicFactor    ,hashCode                  ,3   ,1  ,0
proj2        ,(default package) ,BasicFactor    ,toString                  ,13  ,3  ,0
proj2        ,(default package) ,BasicTerm      ,BasicTerm                 ,4   ,1  ,2
proj2        ,(default package) ,BasicTerm      ,BasicTerm                 ,5   ,1  ,0
proj2        ,(default package) ,BasicTerm      ,merge                     ,18  ,5  ,1
proj2        ,(default package) ,BasicTerm      ,multiply                  ,10  ,3  ,2
proj2        ,(default package) ,BasicTerm      ,negateAll                 ,6   ,2  ,1
proj2        ,(default package) ,BasicTerm      ,printExpr                 ,16  ,4  ,1
proj2        ,(default package) ,BasicTerm      ,getBasicFactors           ,3   ,1  ,0
proj2        ,(default package) ,BasicTerm      ,getFac                    ,3   ,1  ,0
proj2        ,(default package) ,BasicTerm      ,klone                     ,4   ,1  ,0
proj2        ,(default package) ,BasicTerm      ,mul                       ,6   ,1  ,1
proj2        ,(default package) ,BasicTerm      ,add                       ,3   ,1  ,1
proj2        ,(default package) ,BasicTerm      ,negate                    ,3   ,1  ,0
proj2        ,(default package) ,BasicTerm      ,extractFactor             ,5   ,1  ,0
proj2        ,(default package) ,BasicTerm      ,toString                  ,24  ,6  ,0
proj2        ,(default package) ,CustomFunction ,CustomFunction            ,4   ,1  ,2
proj2        ,(default package) ,CustomFunction ,registerFunction          ,3   ,1  ,2
proj2        ,(default package) ,CustomFunction ,getFunction               ,3   ,1  ,1
proj2        ,(default package) ,CustomFunction ,eval                      ,7   ,2  ,1
proj2        ,(default package) ,ExprNode       ,wrapNode                  ,10  ,1  ,1
proj2        ,(default package) ,ExprNode       ,PowerFactor               ,4   ,1  ,2
proj2        ,(default package) ,ExprNode       ,getPow                    ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,getSymbol                 ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,toString                  ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,klone                     ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,FunCallFactor             ,5   ,1  ,3
proj2        ,(default package) ,ExprNode       ,getPow                    ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,getSymbol                 ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,getParaList               ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,klone                     ,7   ,2  ,0
proj2        ,(default package) ,ExprNode       ,ConstFactor               ,3   ,1  ,1
proj2        ,(default package) ,ExprNode       ,getValue                  ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,toString                  ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,klone                     ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,ExprFactor                ,4   ,1  ,2
proj2        ,(default package) ,ExprNode       ,getPow                    ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,getExpr                   ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,toString                  ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,klone                     ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,Term                      ,4   ,1  ,2
proj2        ,(default package) ,ExprNode       ,getExprNodes              ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,getPrefixOperator         ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,toString                  ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,klone                     ,7   ,2  ,0
proj2        ,(default package) ,ExprNode       ,Expr                      ,4   ,1  ,2
proj2        ,(default package) ,ExprNode       ,getTerms                  ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,getPrefixOperators        ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,toString                  ,3   ,1  ,0
proj2        ,(default package) ,ExprNode       ,klone                     ,8   ,2  ,0
proj2        ,(default package) ,PowerFactor    ,PowerFactor               ,4   ,1  ,2
proj2        ,(default package) ,PowerFactor    ,getPow                    ,3   ,1  ,0
proj2        ,(default package) ,PowerFactor    ,getSymbol                 ,3   ,1  ,0
proj2        ,(default package) ,PowerFactor    ,toString                  ,3   ,1  ,0
proj2        ,(default package) ,PowerFactor    ,klone                     ,3   ,1  ,0
proj2        ,(default package) ,FunCallFactor  ,FunCallFactor             ,5   ,1  ,3
proj2        ,(default package) ,FunCallFactor  ,getPow                    ,3   ,1  ,0
proj2        ,(default package) ,FunCallFactor  ,getSymbol                 ,3   ,1  ,0
proj2        ,(default package) ,FunCallFactor  ,getParaList               ,3   ,1  ,0
proj2        ,(default package) ,FunCallFactor  ,klone                     ,7   ,2  ,0
proj2        ,(default package) ,ConstFactor    ,ConstFactor               ,3   ,1  ,1
proj2        ,(default package) ,ConstFactor    ,getValue                  ,3   ,1  ,0
proj2        ,(default package) ,ConstFactor    ,toString                  ,3   ,1  ,0
proj2        ,(default package) ,ConstFactor    ,klone                     ,3   ,1  ,0
proj2        ,(default package) ,ExprFactor     ,ExprFactor                ,4   ,1  ,2
proj2        ,(default package) ,ExprFactor     ,getPow                    ,3   ,1  ,0
proj2        ,(default package) ,ExprFactor     ,getExpr                   ,3   ,1  ,0
proj2        ,(default package) ,ExprFactor     ,toString                  ,3   ,1  ,0
proj2        ,(default package) ,ExprFactor     ,klone                     ,3   ,1  ,0
proj2        ,(default package) ,Term           ,Term                      ,4   ,1  ,2
proj2        ,(default package) ,Term           ,getExprNodes              ,3   ,1  ,0
proj2        ,(default package) ,Term           ,getPrefixOperator         ,3   ,1  ,0
proj2        ,(default package) ,Term           ,toString                  ,3   ,1  ,0
proj2        ,(default package) ,Term           ,klone                     ,7   ,2  ,0
proj2        ,(default package) ,Expr           ,Expr                      ,4   ,1  ,2
proj2        ,(default package) ,Expr           ,getTerms                  ,3   ,1  ,0
proj2        ,(default package) ,Expr           ,getPrefixOperators        ,3   ,1  ,0
proj2        ,(default package) ,Expr           ,toString                  ,3   ,1  ,0
proj2        ,(default package) ,Expr           ,klone                     ,8   ,2  ,0
proj2        ,(default package) ,Main           ,main                      ,18  ,2  ,1
proj2        ,(default package) ,Parser         ,getName                   ,3   ,1  ,0
proj2        ,(default package) ,Parser         ,getPos                    ,3   ,1  ,0
proj2        ,(default package) ,Parser         ,getExpr                   ,3   ,1  ,0
proj2        ,(default package) ,Parser         ,Parser                    ,8   ,1  ,1
proj2        ,(default package) ,Parser         ,getParaList               ,3   ,1  ,0
proj2        ,(default package) ,Parser         ,parse                     ,4   ,1  ,0
proj2        ,(default package) ,Parser         ,parseCustomFunction       ,28  ,6  ,0
proj2        ,(default package) ,Parser         ,expr                      ,19  ,4  ,0
proj2        ,(default package) ,Parser         ,term                      ,26  ,6  ,0
proj2        ,(default package) ,Parser         ,factor                    ,24  ,8  ,0
proj2        ,(default package) ,Parser         ,funCallFactor             ,34  ,8  ,0
proj2        ,(default package) ,Parser         ,varFactor                 ,13  ,3  ,0
proj2        ,(default package) ,Parser         ,number                    ,24  ,5  ,0
proj2        ,(default package) ,Parser         ,constFactor               ,4   ,1  ,0
proj2        ,(default package) ,Parser         ,exprFactor                ,20  ,4  ,0
proj2        ,(default package) ,Parser         ,isAtEnd                   ,3   ,1  ,0
proj2        ,(default package) ,Parser         ,peek                      ,3   ,1  ,0
proj2        ,(default package) ,Parser         ,peek2                     ,8   ,2  ,0
proj2        ,(default package) ,Parser         ,advance                   ,3   ,1  ,0
proj2        ,(default package) ,Parser         ,consume                   ,9   ,2  ,1
proj2        ,(default package) ,Simplifier     ,simplify                  ,3   ,1  ,1
proj2        ,(default package) ,Simplifier     ,simplifyExpr              ,13  ,3  ,2
proj2        ,(default package) ,Simplifier     ,simplifyTerm              ,11  ,3  ,2
proj2        ,(default package) ,Simplifier     ,simplifyFactor            ,22  ,5  ,2
proj2        ,(default package) ,Simplifier     ,applyPowerFactor          ,21  ,3  ,2
proj2        ,(default package) ,Simplifier     ,dispatchFunctions         ,25  ,5  ,3
proj2        ,(default package) ,Simplifier     ,dispatchTriangleFunctions ,4   ,1  ,3
proj2        ,(default package) ,Simplifier     ,dispatchCos               ,29  ,6  ,3
proj2        ,(default package) ,Simplifier     ,dispatchSin               ,29  ,6  ,3
proj2        ,(default package) ,Token          ,Token                     ,5   ,1  ,3
proj2        ,(default package) ,Token          ,getSymbol                 ,3   ,1  ,0
proj2        ,(default package) ,Token          ,getNumber                 ,3   ,1  ,0
proj2        ,(default package) ,Token          ,getType                   ,3   ,1  ,0
proj2        ,(default package) ,Token          ,toString                  ,10  ,3  ,0
proj2        ,(default package) ,Tokenizer      ,Tokenizer                 ,6   ,1  ,1
proj2        ,(default package) ,Tokenizer      ,getTokens                 ,3   ,1  ,0
proj2        ,(default package) ,Tokenizer      ,run                       ,55  ,14 ,0
proj2        ,(default package) ,Tokenizer      ,identifier                ,12  ,3  ,0
proj2        ,(default package) ,Tokenizer      ,number                    ,17  ,3  ,0
proj2        ,(default package) ,Tokenizer      ,peek                      ,8   ,2  ,0
proj2        ,(default package) ,Tokenizer      ,peek2                     ,8   ,2  ,0
proj2        ,(default package) ,Tokenizer      ,advance                   ,3   ,1  ,0
proj2        ,(default package) ,Tokenizer      ,isAtEnd                   ,3   ,1  ,0
proj2        ,util              ,Klone          ,klone                     ,0   ,1  ,0

Project Name ,Package Name      ,Type Name      ,NOF ,NOPF ,NOM ,NOPM ,LOC ,WMC ,NC ,DIT ,LCOM                ,FANIN ,FANOUT
proj2        ,(default package) ,BasicFactor    ,5   ,0    ,22  ,19   ,182 ,47  ,0  ,1   ,0.13636363636363635 ,0     ,0
proj2        ,(default package) ,BasicTerm      ,2   ,0    ,14  ,14   ,114 ,29  ,0  ,1   ,0.14285714285714285 ,0     ,0
proj2        ,(default package) ,CustomFunction ,3   ,0    ,4   ,4    ,22  ,5   ,0  ,0   ,0.5                 ,1     ,1
proj2        ,(default package) ,ExprNode       ,12  ,0    ,30  ,30   ,142 ,33  ,0  ,1   ,0.16666666666666666 ,0     ,0
proj2        ,(default package) ,PowerFactor    ,2   ,0    ,5   ,5    ,20  ,5   ,0  ,0   ,0.0                 ,0     ,0
proj2        ,(default package) ,FunCallFactor  ,3   ,0    ,5   ,5    ,26  ,6   ,0  ,0   ,0.0                 ,0     ,0
proj2        ,(default package) ,ConstFactor    ,1   ,0    ,4   ,4    ,15  ,4   ,0  ,0   ,0.0                 ,0     ,0
proj2        ,(default package) ,ExprFactor     ,2   ,0    ,5   ,5    ,20  ,5   ,0  ,0   ,0.0                 ,0     ,0
proj2        ,(default package) ,Term           ,2   ,0    ,5   ,5    ,24  ,6   ,0  ,0   ,0.0                 ,0     ,0
proj2        ,(default package) ,Expr           ,2   ,0    ,5   ,5    ,25  ,6   ,0  ,0   ,0.0                 ,0     ,0
proj2        ,(default package) ,Main           ,0   ,0    ,1   ,1    ,20  ,2   ,0  ,0   ,-1.0                ,0     ,0
proj2        ,(default package) ,Parser         ,6   ,0    ,20  ,7    ,250 ,58  ,0  ,0   ,0.15                ,0     ,0
proj2        ,(default package) ,Simplifier     ,0   ,0    ,9   ,2    ,159 ,33  ,0  ,0   ,-1.0                ,0     ,0
proj2        ,(default package) ,Token          ,3   ,0    ,5   ,5    ,29  ,7   ,0  ,0   ,0.0                 ,0     ,0
proj2        ,(default package) ,Tokenizer      ,4   ,0    ,9   ,3    ,121 ,28  ,0  ,0   ,0.0                 ,0     ,0
proj2        ,util              ,Klone          ,0   ,0    ,1   ,0    ,3   ,1   ,3  ,0   ,-1.0                ,0     ,0

看起來資料上方法的複雜度不高,但是實際上是用IDEA強行抽取方法降低的圈複雜度和方法長度,其實程式碼結構已經很亂了。

Bug

發現了兩個bug(我感覺可能有更多沒發現的)

  • 資料表示不統一,比如3*x可能表示為Term(3,Factor(1,1))或者Term(1,Factor(3,1))或者之類的情況,化簡時情況沒考慮完整(高複雜度的程式碼導致完整考慮非常困難)
  • 輸出部分每一個層次考慮了不屬於本層次的東西,比如Term在考慮輸出Factor的細節,不符合封裝的思想,導致考慮不充分出現Bug。

然後加了一堆特判改Bug。

程式碼更加沒眼看了,只能重構。

第三次作業

概述

第三次作業進行了重構,由於詞法分析和語法分析部分與簡化部分解耦,可以不用修改,所以工作量尚可(架構崩了,但沒完全崩)。

用完整的層次結構建立了表示式的抽象,並在此之上進行化簡。(程式碼甚至相比第二次作業還有所簡化)

UML

classDiagram class Parser{ -expr: Expr -pos: int -exprFactor() ExprFactor +parse() boolean +parseCustomFunction() boolean -funCallFactor() FunCallFactor -expr() Expr -number() BigInteger -constFactor() ConstFactor -advance() void -varFactor() VarFactor -term() Term -peek() Token -consume(TokenType) void +getExpr() Expr -isAtEnd() boolean +getPos() int } class Simplifier{ -simplifyTerm(Term,HashMap~String,ExprNode~) ArrayList~BasicTerm~ +simplify(Expr) ArrayList~BasicTerm~ -simplifyFactor(ExprNode,HashMap~String,ExprNode~) ArrayList~BasicTerm~ +simplifyExpr(Expr,HashMap~String,ExprNode~) ArrayList~BasicTerm~ -simplifyFactor(ExprNode,HashMap~String,ExprNode~) ArrayList~BasicTerm~ -dispatchTriangleFunctions(ArrayList~BasicTerm~,FunCallFactor, HashMap~String,ExprNode~) -applyPowerFactor(PowerFactor, HashMap~String,ExprNode~) -dispatchFunctions(ExprNode,ArrayList~BasicTerm~,FunCallFactor, HashMap~String,ExprNode~) } class BasicTerm{ -basicFactors: ArrayList~BasicFactor~ -fac: BigInteger +add(BasicTerm) Term +extractFactor() void +toString() String +simplify() void +unwrap() BasicFactor +wrap() BasicExpr +mul(BasicTerm) BasicTerm +mul(BasicFactor) BasicTerm +mergeIn(BasicTerm) void +negate() BasicTerm +add(BasicTerm) BasicTerm +getFac() BigInteger +getBasicFactors() ArrayList~BasicFactor~ } class BasicFactor{ -fac: BigInteger -idx: BigInteger -exprInner BasicExpr -factorType: FactorType +getFac() BigInteger +getIdx() BigInteger +setFac(BigInteger) +setIdx(BigInteger) +getFactorType() FactorType +isOne() Boolean +isZero() Boolea +createCos(BigInteger,BigInteger,BasicExpr) BasicFactor +canMerge(BasicFactor,BasicFactor) boolean +toString() String +createSin(BigInteger,BigInteger, BasicExpr) BasicFactor +createX(BigInteger,BigInteger) BasicFactor +simplify() void +mergeIn(BasicFactor) void +wrap() BasicTerm } class BasicExpr{ -terms: ArrayList<BasicTerm> +add(BasicTerm) BasicExpr +unwrap() BasicExpr +add(BasicExpr) BasicExpr +mul(BasicExpr) BasicExpr +simplify() void +toString() String +negate() BasicExpr } class ExprNode{ << interface >> +wrapNode(ExprNode) Expr } class ExprFactor{ -pow: BigInteger -expr: Expr +toString() String +getExpr() Expr +getPow() BigInteger } class Expr{ -terms: ArrayList~Term~ -prefixOperators: ArrayList~TokenType~ +toString() String +getTerms() ArrayList~Term~ +getPrefixOperators() ArrayList~TokenType~ } class ConstFactor{ -value: BigInteger +toString() String +getValue() BigInteger } class VarFactor{ -pow: BigInteger +toString() String +getPow() BigInteger } class Term{ -prefixOperator: TokenType -exprNodes: ArrayList~ExprNode~ +toString() String +getPrefixOperator() TokenType +getExprNodes() ArrayList~ExprNode~ } class FunCallFactor{ -symbol: String -paraList: ArrayList<ExprNode> -pow: BigInteger +getSymbol() String +getPow() BigInteger +getParaList() ArrayList~ExprNode~ } class Tokenizer{ -tokens: ArrayList~Token~ -peek2() Character -advance() void -number() void -peek() Character +run() boolean -isAtEnd() boolean +getTokens() ArrayList~Token~ -identifier() void } class Token{ -number: BigInteger -type: TokenType -symbol: String +toString() String +getType() TokenType +getSymbol() String +getNumber() BigInteger } class TokenType{ << enumeration>> Add Number SStar Star Sub Symbol LParen RParen Comma Equal } class CustomFunction{ -paraList: ArrayList~String~ -body: ExprNode +eval(ArrayList~ExprNode~) ArrayList~BasicTerm~ } class Klone~T~{ << interface >> klone() T } class Comparable~T~{ << interface >> } class FactorType{ << enumeration >> X Sin Cos } ExprFactor ..|> ExprNode Expr ..|> ExprNode ConstFactor ..|> ExprNode VarFactor ..|> ExprNode Term ..|> ExprNode FunCallFactor --* Term VarFactor --* Term ConstFactor --* Term ExprFactor --* Term Term --* Expr Token *-- TokenType Tokenizer ..> Token Parser ..> Token Simplifier ..> BasicTerm Parser ..> ExprNode Simplifier ..> ExprNode Simplifier ..> CustomFunction BasicFactor ..|> Klone BasicTerm ..|> Klone ExprNode ..|> Klone BasicExpr ..|> Klone BasicFactor --* BasicTerm BasicTerm --* BasicExpr FactorType --* BasicFactor BasicFactor ..|> Comparable BasicTerm ..|> Comparable BasicExpr ..|> Comparable

分析

對主要化簡部分進行了重構,將ArrayList<BasicTerm>封裝成了BasicExpr,並基本上讓各個類各司其職。但是感覺仍然有優化空間,比如Basicxx類有mergeIn,simplify,canMerge等公共方法,可以抽取一個介面。Simplifier類仍然是一堆靜態方法,可以考慮用訪問者模式重構。

度量值

Project Name ,Package Name      ,Type Name      ,MethodName                ,LOC ,CC ,PC
proj3        ,(default package) ,CustomFunction ,CustomFunction            ,4   ,1  ,2
proj3        ,(default package) ,CustomFunction ,registerFunction          ,3   ,1  ,2
proj3        ,(default package) ,CustomFunction ,getFunction               ,3   ,1  ,1
proj3        ,(default package) ,CustomFunction ,eval                      ,7   ,2  ,1
proj3        ,(default package) ,ExprNode       ,wrapNode                  ,10  ,1  ,1
proj3        ,(default package) ,ExprNode       ,PowerFactor               ,4   ,1  ,2
proj3        ,(default package) ,ExprNode       ,getPow                    ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,getSymbol                 ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,toString                  ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,klone                     ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,FunCallFactor             ,5   ,1  ,3
proj3        ,(default package) ,ExprNode       ,getPow                    ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,getSymbol                 ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,getParaList               ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,klone                     ,7   ,2  ,0
proj3        ,(default package) ,ExprNode       ,ConstFactor               ,3   ,1  ,1
proj3        ,(default package) ,ExprNode       ,getValue                  ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,toString                  ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,klone                     ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,ExprFactor                ,4   ,1  ,2
proj3        ,(default package) ,ExprNode       ,getPow                    ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,getExpr                   ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,toString                  ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,klone                     ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,Term                      ,4   ,1  ,2
proj3        ,(default package) ,ExprNode       ,getExprNodes              ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,getPrefixOperator         ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,toString                  ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,klone                     ,7   ,2  ,0
proj3        ,(default package) ,ExprNode       ,Expr                      ,4   ,1  ,2
proj3        ,(default package) ,ExprNode       ,getTerms                  ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,getPrefixOperators        ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,toString                  ,3   ,1  ,0
proj3        ,(default package) ,ExprNode       ,klone                     ,8   ,2  ,0
proj3        ,(default package) ,PowerFactor    ,PowerFactor               ,4   ,1  ,2
proj3        ,(default package) ,PowerFactor    ,getPow                    ,3   ,1  ,0
proj3        ,(default package) ,PowerFactor    ,getSymbol                 ,3   ,1  ,0
proj3        ,(default package) ,PowerFactor    ,toString                  ,3   ,1  ,0
proj3        ,(default package) ,PowerFactor    ,klone                     ,3   ,1  ,0
proj3        ,(default package) ,FunCallFactor  ,FunCallFactor             ,5   ,1  ,3
proj3        ,(default package) ,FunCallFactor  ,getPow                    ,3   ,1  ,0
proj3        ,(default package) ,FunCallFactor  ,getSymbol                 ,3   ,1  ,0
proj3        ,(default package) ,FunCallFactor  ,getParaList               ,3   ,1  ,0
proj3        ,(default package) ,FunCallFactor  ,klone                     ,7   ,2  ,0
proj3        ,(default package) ,ConstFactor    ,ConstFactor               ,3   ,1  ,1
proj3        ,(default package) ,ConstFactor    ,getValue                  ,3   ,1  ,0
proj3        ,(default package) ,ConstFactor    ,toString                  ,3   ,1  ,0
proj3        ,(default package) ,ConstFactor    ,klone                     ,3   ,1  ,0
proj3        ,(default package) ,ExprFactor     ,ExprFactor                ,4   ,1  ,2
proj3        ,(default package) ,ExprFactor     ,getPow                    ,3   ,1  ,0
proj3        ,(default package) ,ExprFactor     ,getExpr                   ,3   ,1  ,0
proj3        ,(default package) ,ExprFactor     ,toString                  ,3   ,1  ,0
proj3        ,(default package) ,ExprFactor     ,klone                     ,3   ,1  ,0
proj3        ,(default package) ,Term           ,Term                      ,4   ,1  ,2
proj3        ,(default package) ,Term           ,getExprNodes              ,3   ,1  ,0
proj3        ,(default package) ,Term           ,getPrefixOperator         ,3   ,1  ,0
proj3        ,(default package) ,Term           ,toString                  ,3   ,1  ,0
proj3        ,(default package) ,Term           ,klone                     ,7   ,2  ,0
proj3        ,(default package) ,Expr           ,Expr                      ,4   ,1  ,2
proj3        ,(default package) ,Expr           ,getTerms                  ,3   ,1  ,0
proj3        ,(default package) ,Expr           ,getPrefixOperators        ,3   ,1  ,0
proj3        ,(default package) ,Expr           ,toString                  ,3   ,1  ,0
proj3        ,(default package) ,Expr           ,klone                     ,8   ,2  ,0
proj3        ,(default package) ,Main           ,main                      ,18  ,2  ,1
proj3        ,(default package) ,Parser         ,getName                   ,3   ,1  ,0
proj3        ,(default package) ,Parser         ,getPos                    ,3   ,1  ,0
proj3        ,(default package) ,Parser         ,getExpr                   ,3   ,1  ,0
proj3        ,(default package) ,Parser         ,Parser                    ,8   ,1  ,1
proj3        ,(default package) ,Parser         ,getParaList               ,3   ,1  ,0
proj3        ,(default package) ,Parser         ,parse                     ,4   ,1  ,0
proj3        ,(default package) ,Parser         ,parseCustomFunction       ,28  ,6  ,0
proj3        ,(default package) ,Parser         ,expr                      ,19  ,4  ,0
proj3        ,(default package) ,Parser         ,term                      ,26  ,6  ,0
proj3        ,(default package) ,Parser         ,factor                    ,24  ,8  ,0
proj3        ,(default package) ,Parser         ,funCallFactor             ,34  ,8  ,0
proj3        ,(default package) ,Parser         ,varFactor                 ,13  ,3  ,0
proj3        ,(default package) ,Parser         ,number                    ,24  ,5  ,0
proj3        ,(default package) ,Parser         ,constFactor               ,4   ,1  ,0
proj3        ,(default package) ,Parser         ,exprFactor                ,20  ,4  ,0
proj3        ,(default package) ,Parser         ,isAtEnd                   ,3   ,1  ,0
proj3        ,(default package) ,Parser         ,peek                      ,3   ,1  ,0
proj3        ,(default package) ,Parser         ,peek2                     ,8   ,2  ,0
proj3        ,(default package) ,Parser         ,advance                   ,3   ,1  ,0
proj3        ,(default package) ,Parser         ,consume                   ,9   ,2  ,1
proj3        ,(default package) ,Simplifier     ,simplify                  ,5   ,1  ,1
proj3        ,(default package) ,Simplifier     ,simplifyExpr              ,13  ,3  ,2
proj3        ,(default package) ,Simplifier     ,simplifyTerm              ,11  ,3  ,2
proj3        ,(default package) ,Simplifier     ,simplifyFactor            ,21  ,5  ,2
proj3        ,(default package) ,Simplifier     ,applyPowerFactor          ,17  ,3  ,2
proj3        ,(default package) ,Simplifier     ,dispatchFunctions         ,28  ,6  ,3
proj3        ,(default package) ,Simplifier     ,dispatchTriangleFunctions ,10  ,2  ,3
proj3        ,(default package) ,Token          ,Token                     ,5   ,1  ,3
proj3        ,(default package) ,Token          ,getSymbol                 ,3   ,1  ,0
proj3        ,(default package) ,Token          ,getNumber                 ,3   ,1  ,0
proj3        ,(default package) ,Token          ,getType                   ,3   ,1  ,0
proj3        ,(default package) ,Token          ,toString                  ,10  ,3  ,0
proj3        ,(default package) ,Tokenizer      ,Tokenizer                 ,6   ,1  ,1
proj3        ,(default package) ,Tokenizer      ,getTokens                 ,3   ,1  ,0
proj3        ,(default package) ,Tokenizer      ,run                       ,55  ,14 ,0
proj3        ,(default package) ,Tokenizer      ,identifier                ,12  ,3  ,0
proj3        ,(default package) ,Tokenizer      ,number                    ,17  ,3  ,0
proj3        ,(default package) ,Tokenizer      ,peek                      ,8   ,2  ,0
proj3        ,(default package) ,Tokenizer      ,peek2                     ,8   ,2  ,0
proj3        ,(default package) ,Tokenizer      ,advance                   ,3   ,1  ,0
proj3        ,(default package) ,Tokenizer      ,isAtEnd                   ,3   ,1  ,0
proj3        ,util              ,Klone          ,klone                     ,0   ,1  ,0
proj3        ,values            ,BasicExpr      ,BasicExpr                 ,3   ,1  ,1
proj3        ,values            ,BasicExpr      ,BasicExpr                 ,3   ,1  ,0
proj3        ,values            ,BasicExpr      ,mul                       ,9   ,3  ,1
proj3        ,values            ,BasicExpr      ,negate                    ,6   ,2  ,0
proj3        ,values            ,BasicExpr      ,add                       ,4   ,1  ,1
proj3        ,values            ,BasicExpr      ,add                       ,4   ,1  ,1
proj3        ,values            ,BasicExpr      ,simplify                  ,18  ,5  ,0
proj3        ,values            ,BasicExpr      ,unwrap                    ,11  ,3  ,0
proj3        ,values            ,BasicExpr      ,toString                  ,14  ,4  ,0
proj3        ,values            ,BasicExpr      ,compareTo                 ,14  ,4  ,1
proj3        ,values            ,BasicExpr      ,klone                     ,7   ,2  ,0
proj3        ,values            ,BasicFactor    ,BasicFactor               ,6   ,1  ,4
proj3        ,values            ,BasicFactor    ,createX                   ,3   ,1  ,2
proj3        ,values            ,BasicFactor    ,createCos                 ,3   ,1  ,3
proj3        ,values            ,BasicFactor    ,createSin                 ,3   ,1  ,3
proj3        ,values            ,BasicFactor    ,createTriangle            ,11  ,3  ,4
proj3        ,values            ,BasicFactor    ,canMerge                  ,3   ,1  ,2
proj3        ,values            ,BasicFactor    ,getFactorString           ,25  ,7  ,3
proj3        ,values            ,BasicFactor    ,simplify                  ,22  ,6  ,0
proj3        ,values            ,BasicFactor    ,mergeIn                   ,4   ,1  ,1
proj3        ,values            ,BasicFactor    ,wrap                      ,5   ,1  ,0
proj3        ,values            ,BasicFactor    ,isOne                     ,3   ,1  ,0
proj3        ,values            ,BasicFactor    ,isZero                    ,3   ,1  ,0
proj3        ,values            ,BasicFactor    ,klone                     ,3   ,1  ,0
proj3        ,values            ,BasicFactor    ,getFactorType             ,3   ,1  ,0
proj3        ,values            ,BasicFactor    ,getFac                    ,3   ,1  ,0
proj3        ,values            ,BasicFactor    ,setFac                    ,3   ,1  ,1
proj3        ,values            ,BasicFactor    ,getIdx                    ,3   ,1  ,0
proj3        ,values            ,BasicFactor    ,setIdx                    ,3   ,1  ,1
proj3        ,values            ,BasicFactor    ,compareTo                 ,23  ,5  ,1
proj3        ,values            ,BasicFactor    ,toString                  ,28  ,7  ,0
proj3        ,values            ,BasicTerm      ,BasicTerm                 ,4   ,1  ,2
proj3        ,values            ,BasicTerm      ,BasicTerm                 ,5   ,1  ,0
proj3        ,values            ,BasicTerm      ,canMerge                  ,14  ,4  ,2
proj3        ,values            ,BasicTerm      ,getBasicFactors           ,3   ,1  ,0
proj3        ,values            ,BasicTerm      ,getFac                    ,3   ,1  ,0
proj3        ,values            ,BasicTerm      ,setFac                    ,3   ,1  ,1
proj3        ,values            ,BasicTerm      ,klone                     ,4   ,1  ,0
proj3        ,values            ,BasicTerm      ,mul                       ,6   ,1  ,1
proj3        ,values            ,BasicTerm      ,mul                       ,4   ,1  ,1
proj3        ,values            ,BasicTerm      ,add                       ,3   ,1  ,1
proj3        ,values            ,BasicTerm      ,negate                    ,3   ,1  ,0
proj3        ,values            ,BasicTerm      ,extractFactor             ,4   ,1  ,0
proj3        ,values            ,BasicTerm      ,simplify                  ,20  ,5  ,0
proj3        ,values            ,BasicTerm      ,mergeIn                   ,3   ,1  ,1
proj3        ,values            ,BasicTerm      ,wrap                      ,5   ,1  ,0
proj3        ,values            ,BasicTerm      ,unwrap                    ,13  ,3  ,0
proj3        ,values            ,BasicTerm      ,toString                  ,24  ,6  ,0
proj3        ,values            ,BasicTerm      ,compareTo                 ,17  ,5  ,1

Project Name ,Package Name      ,Type Name      ,NOF ,NOPF ,NOM ,NOPM ,LOC ,WMC ,NC ,DIT ,LCOM                ,FANIN ,FANOUT
proj3        ,(default package) ,CustomFunction ,3   ,0    ,4   ,4    ,22  ,5   ,0  ,0   ,0.5                 ,1     ,1
proj3        ,(default package) ,ExprNode       ,12  ,0    ,30  ,30   ,142 ,33  ,0  ,1   ,0.16666666666666666 ,0     ,0
proj3        ,(default package) ,PowerFactor    ,2   ,0    ,5   ,5    ,20  ,5   ,0  ,0   ,0.0                 ,0     ,0
proj3        ,(default package) ,FunCallFactor  ,3   ,0    ,5   ,5    ,26  ,6   ,0  ,0   ,0.0                 ,0     ,0
proj3        ,(default package) ,ConstFactor    ,1   ,0    ,4   ,4    ,15  ,4   ,0  ,0   ,0.0                 ,0     ,0
proj3        ,(default package) ,ExprFactor     ,2   ,0    ,5   ,5    ,20  ,5   ,0  ,0   ,0.0                 ,0     ,0
proj3        ,(default package) ,Term           ,2   ,0    ,5   ,5    ,24  ,6   ,0  ,0   ,0.0                 ,0     ,0
proj3        ,(default package) ,Expr           ,2   ,0    ,5   ,5    ,25  ,6   ,0  ,0   ,0.0                 ,0     ,0
proj3        ,(default package) ,Main           ,0   ,0    ,1   ,1    ,20  ,2   ,0  ,0   ,-1.0                ,0     ,0
proj3        ,(default package) ,Parser         ,6   ,0    ,20  ,7    ,250 ,58  ,0  ,0   ,0.15                ,0     ,0
proj3        ,(default package) ,Simplifier     ,0   ,0    ,7   ,2    ,107 ,23  ,0  ,0   ,-1.0                ,0     ,3
proj3        ,(default package) ,Token          ,3   ,0    ,5   ,5    ,29  ,7   ,0  ,0   ,0.0                 ,0     ,0
proj3        ,(default package) ,Tokenizer      ,4   ,0    ,9   ,3    ,121 ,28  ,0  ,0   ,0.0                 ,0     ,0
proj3        ,util              ,Klone          ,0   ,0    ,1   ,0    ,3   ,1   ,4  ,0   ,-1.0                ,0     ,0
proj3        ,values            ,BasicExpr      ,1   ,0    ,11  ,11   ,96  ,27  ,0  ,1   ,0.0                 ,3     ,2
proj3        ,values            ,BasicFactor    ,4   ,0    ,20  ,19   ,167 ,43  ,0  ,1   ,0.0                 ,3     ,3
proj3        ,values            ,BasicTerm      ,2   ,0    ,18  ,18   ,142 ,36  ,0  ,1   ,0.0                 ,4     ,2

簡化部分的複雜度被分解,圈複雜度降低,可以看到BasicTerm BasicFactor BasicExpr 的內聚缺乏度為0.0,度量值分析得到封裝是有效的。

Bug

重構很有效,不僅課下debug時間要少於第二次作業。而且強測和互測都沒有發現Bug(自動生成資料測試在強測前發現了一個和指導書理解有關的bug,很好解決,即sum下界大於上界)。

程式碼架構真的很重要。

思考

簡化表示式演算法

我的演算法只能在同一層次進行化簡,對cos(x)**2+sin(x)**2的處理會非常複雜,也沒有想到很好的方法。

不可變資料結構與所有權

在C++等手動管理記憶體的語言中,為了減少記憶體洩漏的風險,需要用到所有權的概念,比如方法的意圖是拿走這個物件還是保證只獲取這個物件的引用。這樣來保證物件被釋放且只被釋放一次。

雖然Java有GC不需要我們手動管理記憶體,但是運用所有權可以減少潛在的Bug。比如我的一段存在Bug的Java程式碼的等價Rust程式碼長這樣。(已簡化)

//impl BasicTerm
fn unwrap(&mut self) -> BasicFactor{
    if self.basicFactors.len() == 1{
        //判斷能不能拆一層把只有一個因子的項拆成因子
        ...
        if canUnwrap  {
            return basicFactors[0];
        }
	}
}

因為Rust的所有權模型,這無法通過編譯,因為我們不能把BasicTerm中的BasicFactor移出去,因為我們只有它的可變引用。

Java不阻止這種行為,但是Bug不在編譯期體現就在執行期體現,這樣移出去的BasicFactor仍然指向原來BasicTerm裡的BasicFactor,如果我們把它當作兩個物件分別修改,就會出現難以定位的問題(我就被這卡了好久)。

解決方法是複製一份再操作,或者使用不可變物件,想修改只能複製(注意深複製

hack策略

如果是手工構造資料,可能資料不在於長,而在於準確命中可能的邊界條件。

比如

cos(sin(cos(sin(0))))
-+ - 0

等。長的資料可能是同質化的,其實效果和短資料一樣。

同時,資料也應該有針對性,比如第二個資料是我在閱讀某位同學的程式碼時發現他對符號的處理讓我迷惑(看不懂),於是整了這麼一個數據,然後真中了。。

當然,如果能夠自己寫評測機當然更好(但是會增加工作量)。