今天說說德摩根定律在編程中的實踐,題目看的很嚇人,其實只要有一點點的高中數學知識就能看懂,而且這部分知識掌握后可以很快的運用到專案中,投資收益比非常高,
如果你覺得我的文章對你有幫助,在收藏的程序中,一定要記得點贊哦,謝謝你,這對我真的很重要??!
一、緣起:一段讓人頭大的邏輯判斷
這兩天在重構一些老專案,重構程序中遇到了一個讓人非常頭大的邏輯判斷:
if(!((A && B) || C)) {
// do something
} else {
// do something
}
看了這段代碼,我人都傻了,從里向外一層一層梳理邏輯時,我的大腦活動是這樣的:
短短一行的邏輯判斷里,與或非三個運算子都用上了,尤其是最后那個小括號一圈全體取反的操作,我腦子直接炸了,要知道人腦是很不擅長或運算和非運算的,更不要說這些運算組合在一起了,
又花了五分鐘嘗試從代碼背景關系中梳理業務邏輯無果后,我重新審視了這個問題:如果業務上不好處理這個問題,能不能從理論上找到突破口?
方向找對后,我很快就找到了解決方案,那就是離散數學里的德摩根定律(De Morgan's laws) ,
二、什么是德摩根定律
德摩根定律我們其實很早就接觸過了,高中數學的集合部分就講過,大學離散數學的集合運算和布爾代數部分也有所提及,
德摩根定律在離散數學的很多場景里都出現過,它一共有兩個關系:
在命題邏輯里,可以這樣表示:
其中 表示邏輯非運算子(NOT, !), 表示邏輯或運算子(OR, ||), 表示邏輯與運算子(AND, &&)
在集合里可以這樣表示:
其中 A 和 B 表示集合,集合上的橫線表示取補集, 表示取交集, 表示取并集,
在布爾代數里可以這樣表示:
其中 表示布爾積(AND), 表示布爾和(OR),上劃線表示補(NOT),
上面的公式還可以用文字描述:
非( 或 )等價于(非 )且(非 )
非( 且 )等價于(非 )或(非 )
或者用程式員熟悉的與或非邏輯運算子表示:
!(P || Q) = !P && !Q
!(P && Q) = !P || !Q
公式已經擺在這里了,肯定可以直接用了,但是用的時候還是不太放心,最好還是自己驗證一下,我們可以用真值表對 做個直觀的驗證:
| 0 | 0 | 1 | 1 | 0 | 1 | 1 |
| 0 | 1 | 1 | 0 | 0 | 1 | 1 |
| 1 | 0 | 0 | 1 | 0 | 1 | 1 |
| 1 | 1 | 0 | 0 | 1 | 0 | 0 |
我們也可以用 Venn 圖對 做個可視化驗證:

更復雜的數學推導我這里就不多說了,感興趣的同學可以自行搜索學習,
三、解決問題
具體到我一開始說的那個條件判斷上,我們可以用德摩根定律把原運算式拆開:
!((A && B) || C)
== !(A && B) && !C // 德摩根律
== (!A || !B) && !C // 德摩根律
== (!A && !C) || (!B && !C) // 分配律
用分配律轉化后,經過代碼的背景關系分析,我發現在這段代碼的業務場景中, !A 等價于 C,所以上面的式子還可以化簡:
(!A && !C) || (!B && !C)
== (C && !C) || (!B && !C) // !A 等價于 C(從業務上分析的,不具備普遍意義)
== false || (!B && !C) // C && !C 必定為 false
== !B && !C
== A && !B // A 等價于 !C(從業務上分析的)
到這里,我成功的把原來一段讓人腦袋爆炸的判斷陳述句化簡為一段直白易懂的運算式,轉換后的代碼無論是從理解上還是后期維護上都比原來容易很多,
四、化簡還有什么招?
與或非三者一起用的場景可以嘗試用德摩根定律化簡,在其它場景下,還可以利用其它運算律進行轉換,比如說前面我就用了分配律,類似于積之和展開式的化簡,我們還可以用卡諾圖進行分析,
例如一個場景試圖化簡布爾函式的一個積之展開式: ,就可以用卡諾圖進行分析:
| 1 | ||
| 1 | 1 |
根據圖示可以輕易得出最后的化簡結果為 ,
如果變數超過 4 個,卡諾圖就非常復雜了,這時候可以用奎因-莫克拉斯基方法進行化簡,限于篇幅也不多介紹了,感興趣的同學可以自行搜索,
在此我再多說一句,如果真的出現用 4 個以上的子狀態去決定最終的行為時,問題的關鍵就不是化簡,而是頂層設計上就出了問題了,這時候需要停下來好好思考是不是模型的設計抽象程度不夠,把過多的內部狀態暴露了出來等等,這個得具體業務具體分析,一昧的堆 if else 或加 flag 是解決不了問題的,只會導致代碼的腐化最終無法維護,
歡迎大家關注我的微信公眾號:鹵蛋實驗室,目前專注前端技術,對圖形學也有一些微小研究,
也可以加我的微信 egg_labs,歡迎大家來撩,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/181851.html
標籤:其他
