写在前面,了解数学在编程中的应用。由于这两天考场停电,这两天无事可做。你闲着干什么?想着再写一篇文章来唠叨。于是就有了今天的文章。选题的原因是上个月,社区有人提出了这样一个问题——如何简化这个JS判断,搞得我头晕constisDel=(op,o)=>{letfal=false;如果(op.is_show_lock&&op.is_show_sf&&op.is_show_bz){如果(o.is_lock&&o.is_sf&&o.is_bz){fal=false;}else{fal=true;}}elseif(op.is_show_lock&&op.is_show_sf){if(o.is_lock&&o.is_sf){fal=false;}else{fal=true;}}elseif(op.is_show_lock&&op.is_show_bz){if(o.is_lock&&o.is_bz){fal=false;}else{fal=true;}}elseif(op.is_show_sf&&op.is_show_bz){if(o.is_sf&&o.is_bz){fal=false;}else{fal=true;}}elseif(op.is_show_lock){if(o.is_lock){fal=false;}else{fal=true;}}否则如果(操作.is_show_sf){如果(o.is_sf){fal=false;}else{fal=true;}}elseif(op.is_show_bz){if(o.is_bz){fal=false;}else{fal=true;}}返回fal;};可以看出,这段代码的主要逻辑是根据几个字段判断最终结果并输出布尔值。作者最终给出的答案是——constisRemove=(op,o)=>(op.is_show_lock&&!o.is_lock)||(op.is_show_sf&&!o.is_sf)||(op.is_show_bz&&!o.is_bz)那么如何简化呢?看到上面一长串的逻辑判断,很明显字段的重复使用太多了。笔者第一感觉应该是用布尔代数来化简吧。这里涉及到两个知识点。BooleanalgebraRules和Booleanalgebraicoperationlaws,这两个的理论知识不再赘述,大家可以点击链接查看或者使用常用的搜索引擎搜索相关资料。让我们开门见山。化繁为简首先我们回头看题主的代码,发现满足true的条件比较少【ps:因为false不仅包括if里面的条件,还包括不满足else的条件,这个是作者第一次回答yesThebugoftimedelay],然后列出所有满足true的布尔表达式如下:op.is_show_lock&&op.is_show_sf&&op.is_show_bz&&!(o.is_lock&&o.is_sf&&o.is_bz)||op.is_show_lock&&op.is_show_sf&&!(o.is_lock&&o.is_sf)||op.is_show_lock&&op.is_show_bz&&!(o.is_lock&&o.is_bz)||op.is_show_sf&&op.is_show_bz&&!(o.is_sf&&o.is_bz)||op.is_show_lock&&!o.is_lock||op.is_show_sf&&!o.is_sf||op.is_show_bz&&!o.is_bz字段只是一种表示,所以这里可以用字母代替,简化表达。假设:op.is_show_lock->Aop.is_show_sf->Bop.is_show_bz->Co.is_lock->ao.is_sf->bo.is_bz->c又因为需要用数学语言来表达,在数学中:&&->·||->+!->'那么,代码表示为以下布尔代数:A·B·C·(a·b·c)'+A·B·(a·b)'+A·C·(a·c)′+B·C·(b·c)′+A·a′+B·b′+C·c′下一步就是对这个布尔代数公式应用布尔运算法则进行化简,得到最终的最优解布尔代数。步德摩根定律(inversionlaw):(a+b)'=a'b',(ab)'=a'+b'.ABC(a'+b'+c')+A·B·(a′+b′)+A·C·(a′+c′)+B·C·(b′+c′)+A·a′+B·b′+C·c′分布规律:a·(b+c)=(a·b)+(a·c),(a+b)·c=(a·c)+(b·c)来自1步原来所有abc都是a'b'c',则这里再做一次代入,每一次代入表示为xyz;那么根据分配律:A·B·C·x+A·B·C·y+ABCz+ABx+ABy+ACx+ACz+BCy+BCz+Ax+By+Cz对换律:a+b=b+a,ab=ba。组合定律:(a+b)+c=a+(b+c),(ab)c=a·(b·c)。从第二步可以看出,有两个子项具有共同的代数表达式,如:A·B·x,A·x;根据交换律和结合律,它们可以组合运算,这里以这两个为例:A·B·x+A·x是零齐整(单位律):a+0=a,a·1=A。A·B·x+A·x·1分配律:a·(b+c)=(a·b)+(a·c),(a+b)·c=(a·c)+(b·c)A·x·(B+1)定律(ExtremeElementLaw):a+1=1,a0=0.Ax根据步骤3~6的运算,ABx+Ax=得到Ax,重复上述步骤对其他成对子代数进行代数运算,最终得到代数公式:Ax+By+Cz至此,布尔代数公式无法再优化,所以可以按照原来的约定转化为如下代码:(op.is_show_lock&&!o.is_lock)||(op.is_show_sf&&!o.is_sf)||(op.is_show_bz&&!o.is_bz)我做开发5年了,没遇到过这个问题,这样的代码出现的概率应该比较小。即使它发生了,大多数人可能会在答案中使用其他解决方案,但大多数跳不出循环,复杂度直接从O(1)变成了O(N)。虽然最终影响微乎其微,但了解其他更好的方案无伤大雅,同时也提高了可读性。如果读者遇到这样的代码,可以尝试使用这个技巧
