假如你的同事寫了這樣的代碼:a && d || b && c && !d || (!a || !b) && c

假設看到了這樣的代碼:javascript

if (a && d || b && c && !d || (!a || !b) && c) {
  console.log('pass')
} else {
  console.log('fail')
}
複製代碼

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

固然,這段代碼是我參考一個沸點(@隔壁村的李二狗)僞造的,希望你和你的同事都別這麼寫。canvas

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

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

答案是確定的!動畫

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

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

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

爲了方便表達,JS中的與或非,我用布爾代數裏面的表示方法(感謝掘金支持latex公式):cdn

a\&\&b \Rightarrow AB

a||b \Rightarrow A+B

!a \Rightarrow \overline{A}

所以 a && d || b && c && !d || (!a || !b) && c 能夠表達爲:

AD+BC\overline{D}+(\overline{A}+\overline{B})C

轉化後優先級清晰多了。

如今的問題是,咱們如何化簡這個邏輯表達式。

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

  1. A+A=A、A+\overline{A}=1

  2. AB+A\overline{B}=A

  3. A+AB=A

  4. \overline{A}+\overline{B}=\overline{AB}、\overline{A}\overline{B}=\overline{A+B}

  5. AB+\overline{A}C=AB+\overline{A}C+BC

前四個公式很好理解。好比A+\overline{A}=1,本身或上本身否,固然爲 true。

關鍵在於第5個公式沒那麼直觀,能夠經過畫圖簡單說明下(其餘公式均可以相似推導)。

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

再看\overline{A}C,如圖中綠色區域:

則兩者之和爲:

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

由於粉色區域本來就在前兩者之和裏面,所以加多少BC次都是同樣的。

注意最後這個公式核心特色:A\overline{A}是以和出現的。

有了這幾個公式做爲鋪墊,咱們就能夠正式推導了(原沸點配圖中有):

AD+BC\overline{D}+(\overline{A}+\overline{B})C

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

AD+BC\overline{D}+\overline{AB}C

注意到前兩項分別有D\overline{D},符合第5條:

AD+BC\overline{D}+ABC+\overline{AB}C

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

AD+BC\overline{D}+C

最後兩項知足第3條:

AD+C

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

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

if (a && d || c) {
  console.log('pass')
} else {
  console.log('fail')
}
複製代碼

真清爽。

點擊驗證兩者等價性

感謝你看到這裏,但願有所幫助。

今年年底,本人立了個flag,2020年要研究透canvas動畫技術。

圖中二維碼是個人惟一微信號,若有掘友想加的,麻煩備註下來源哈,好比【掘金】。

本文完。

相關文章
相關標籤/搜索