zoukankan      html  css  js  c++  java
  • 化简复杂逻辑,编写紧凑的if条件语句(二):依据if子句顺序化简条件

    化简复杂逻辑,编写紧凑的if条件语句》已经得出了跳、等、飞、异常的各自条件,方便起见这里重新贴一下。

    • 立即跃迁:!a && b && d
    • 等待跃迁:!a && b && !d
    • 飞往星区:!b && c || a && c
    • 抛出异常:a && !c || !b && !c

    这四个条件已经是“全集”了,或起来等于True。

    按照跳、等、飞、异常的顺序写if-else if-...else-end语句,则是这样的:

                if (!a && b && d)
                {
                    //立即跃迁
                }
                else if (!a && b && !d)
                {
                    //可以跃迁但跳跃门附近有船。
                    //为避免撞船,等待一会儿
                }
                else if (!b && c || a && c)
                {
                    //老老实实飞过去
                }
                else//a && !c || !b && !c
                {
                    //异常
                }

    可以发现,第一第二句if里,!a && b 是重复的。大多数人可能希望把它改成嵌套的if。

                if (!a && b)
                {
                    if (d)
                    { 
                        //立即跃迁
                    }
                    else//!d
                    { 
                        //可以跃迁但跳跃门附近有船。
                        //为避免撞船,等待一会儿
                    }
                }

    这种方法诚然可行,但它是基于开发人员的直觉或经验,不是数学上的推导。当条件复杂时,人们就会晕头转向了。

    问题

    我这里使用正规的数学方法化简第二句if。把程序问题转化为数学问题,就是:已知!a && b && d=false,化简!a && b && !d。

    解答(法1)

    解决此类问题的一般方法是代入法。

     & lnot a wedge b wedge lnot d \ =& lnot a wedge b wedge lnot d wedge mathbf{F} \ =& lnot a wedge b wedge lnot d wedge  lnot a wedge b wedge d\ =& lnot a wedge b

    用Mathematica的话还是用BooleanMinimize方法。

    问题的等价表述

    还有另一种数学表述:已知lnot(x wedge y)
ightarrow left [ (x wedge lnot y) Leftrightarrow z 
ight ]是个永真式,求解z。这个式子的意思是在x && y==false的情况下, x && !y与z总是给出相同的值。

    解答(法2)

    先把式子化简,并变换为合取范式。


    Mathematica 7.0里符号似乎在Basic Math Assistant窗口里没有,要用ESC equivESC打出。

    尽量使z出现的次数减少,再手工变换一下。

     & (lnot a vee lnot z) wedge (a vee lnot b vee d vee z) wedge (b vee lnot z) \ =& (a vee lnot b vee d vee z) wedge (lnot a vee lnot z) wedge(b vee lnot z) \ =& (a vee lnot b vee d vee z) wedge left [  (lnot a wedge b)vee lnot z
ight ] \ =& left [lnot (lnot a wedge  b) vee d vee z 
ight ] wedge left [(lnot a wedge b)vee lnot z 
ight ] \

    如果要使其为永真式,则左右两个括号里都得是永真式。在左边配一下,z可以等于lnot a wedge  blnot d;在右边配一下,z可以等于lnot a wedge  b。所以,z等于lnot a wedge  b

    这个方法疑似比较难凑。

    化简if条件

    已知!a && b && d = false,化简!a && b && !d。刚才已经算过了,得!a && b。

    已知!a && b && d=!a && b && !d=false,化简!b && c || a && c。用法1,得(! a && b) || c。(似乎并没有简单多少)

    已知!a && b && d=!a && b && !d=!b && c || a && c=false,化简a && !c || !b && !c。得True。

    现在代码可以优化成

                if (!a && b && d)
                {
                    //立即跃迁
                }
                else if (!a && b)
                {
                    //可以跃迁但跳跃门附近有船。
                    //为避免撞船,等待一会儿
                }
                else if ((!a && b)|| c)
                {
                    //老老实实飞过去
                }
                else//a && !c || !b && !c
                {
                    //异常
                }

    还有个问题。if条件的先后顺序影响了语句的化简结果。什么样的顺序才能得出最简表达呢?

  • 相关阅读:
    编译linux内核问题
    linux驱动路径
    plateform_driver_register和plateform_device_register区别
    linux总线、设备和设备驱动的关系
    linux设备驱动模型
    一堆Offer怎么选?这样做就不纠结了
    解决问题最简单的方法
    Android ScrollView嵌套GridView导致GridView只显示一行item
    84. Spring Boot集成MongoDB【从零开始学Spring Boot】
    接手别人的代码,死的心有吗?
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3292231.html
Copyright © 2011-2022 走看看