2013-03-18 75 views
3

考慮以下三個函數,它們的行爲都是相同的,使用不同的代碼實現相同的事情(例子用JavaScript編寫,我特別感興趣的是應用於JavaScript的答案但這個問題真的可以應用到具有類似構造的語言):邏輯上類似代碼的循環複雜性

// Random number from 0-9 
var x = Math.floor(Math.random() * 10); 

// JSHint reports a cyclomatic complexity of 3 
function a() { 
    if (x === 0) { 
     return "First"; 
    } else if (x === 1 || x === 2) { 
     return "Second"; 
    } 
    return "Third"; 
} 

// JSHint reports a cyclomatic complexity of 4 
function b() { 
    switch (x) { 
    case 0: 
     return "First"; 
    case 1: 
    case 2: 
     return "Second"; 
    default: 
     return "Third"; 
    } 
} 

// JSHint reports a cyclomatic complexity of 1 
function c() { 
    return x === 0 ? "First" : x === 1 || x === 2 ? "Second" : "Third"; 
} 

// All three functions return the same value 
console.log(a(), b(), c()); 

JSComplexity工具報告的所有三個功能有4複雜性,這意味着||運營商作爲獨立的分支處理,因爲是秋天 - 通過case聲明。 JSHint似乎並不關心||運算符,但它確實能夠以相同的方式處理後續的case語句。它似乎讓條件操作符完全錯誤。

在計算圈複雜度時,應該將下降的case語句和邏輯「或」運算符視爲獨立分支?三元條件怎麼樣(我認爲這更簡單,JSHint在這種情況下顯然是錯誤的)?以上所有三個功能都具有相同的圈複雜度嗎?

+0

僅供參考,JSHint現在報告所有這三個功能有4. – JLRishe 2017-11-03 20:06:08

回答

7

循環複雜度是通過代碼的線性無關路徑的數量。雖然跌破case是空洞的,但我相信這是一條不同的道路。所以問題是||是否引入了一個新的分支?

我只是想出來,在這裏,但我認爲,因爲JavaScript對條件進行短路評估,所以我們確實得到了兩個分支。例如,你的a功能等同於:

function a() { 
    if (x === 0) { 
     return "First"; 
    } else if (x === 1) { 
     return "Second"; 
    } else if (x === 2) { 
     return "Second"; 
    } else { 
     return "Third"; 
    } 
} 

...其中有4個分公司,儘管他們兩個執行相同的功能。 (即線性獨立於邊緣而不是頂點)。但是,如果JS沒有進行短路評估,我傾向於考慮x === 1 || x === 2只調用一個分支。

因此,要回答你的問題,我想你的函數的所有三個應該有相同的圈複雜度:4

+0

+1複雜,謝謝,我同意這一點 - 所有這三個函數應該具有相同的複雜度4.在JSHint中肯定有一些錯誤修復需要。在接受這個答案之前,我會稍微等一下,如果有其他意見,鼓勵進一步的答案! – 2013-03-18 15:25:48