你寫這樣的Java代碼,不怕同事打你嘛?

假設看到了這樣的代碼,你是否一口老血噴在屏幕上?現在的問題是,面對如此代碼,這麼複雜的邏輯,能否優化?

  1. if (a && d || b && c && !d || (!a || !b) && c) { 
  2.   console.log('pass') 
  3. } else { 
  4.   console.log('fail') 

你是否一口老血噴在屏幕上?

當然,這段代碼是我參考一個掘金沸點(@隔壁村的李二狗)僞造的,但願你和你的同事都別這麼寫。

能寫出這種與或非,如果不是邏輯不清,那麼估計只有一種可能,需求變更很多次,多人修改後的結果。。

現在的問題是,面對如此代碼,這麼複雜的邏輯,能否優化?

答案是肯定的!

這種問題的探究來自於一門數學:布爾代數或邏輯代數。

說到布爾,我們開發者對此太熟悉了。不就是 true 和 false 嘛。

布爾代數這門課,大學裏應該或多或少都講些吧。因爲我是數學專業畢業的,看到這種問題必須記錄一下,也順便複習一下。

爲了方便表達,JS 中的與或非,我用布爾代數裏面的表示方法:

因此 a && d || b && c && !d || (!a || !b) && c 可以表達爲:

轉化後優先級清晰多了。

現在的問題是,我們如何化簡這個邏輯表達式。

還好有一些常用結論可供我們使用:

前四個公式很好理解。比如,自己或上自己否,當然爲 true。

關鍵在於第 5 個公式沒那麼直觀,可以通過畫圖簡單說明下(其他公式都可以類似推導)。

首先看部分,如圖中綠色區域:

再看,如圖中綠色區域:

則二者之和爲:

而部分正是圖中粉色區域:

因爲粉色區域原本就在前二者之和裏面,因此加多少次都是一樣的。

注意最後這個公式核心特點:和是以和出現的。

有了這幾個公式作爲鋪墊,我們就可以正式推導了(原沸點配圖中有):

根據第 4 條,替換最後一項:

注意到前兩項分別有和,符合第 5 條:

此時最後兩項,符合第 2 條:

最後兩項,其中一項爲,另外一項也包含,滿足第 3 條:

至此化簡完了。真是不可以思議,B 沒了!

此時開篇的代碼簡化成了這樣:

  1. if (a && d || c) { 
  2.   console.log('pass') 
  3. } else { 
  4.   console.log('fail') 

真清爽。

感謝你看到這裏,希望有所幫助。

發佈了32 篇原創文章 · 獲贊 470 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章