减少此方法的布尔表达式复杂度?

时间:2014-08-08 17:29:57

标签: java algorithm

这个isValid()方法最多可以设置6个属性以便进行验证。如果未设置特定属性,则不需要对其进行验证。逻辑似乎正在起作用我希望它如何工作。如何降低此方法的布尔表达式复杂度?

import java.util.ArrayList;
import java.util.List;

public class Valid {

private int foo;
private int bar;
private int foobar;
private String foofoo;
private String barbar;
private String foobarfoobar;

private int myfoo;
private int mybar;
private int myfoobar;
private String myfoofoo;
private List<String> mybarbarlist = new ArrayList<String>();
private String myfoobarfoobar;

private boolean validate;

public boolean isValid() {

    validate = false;

    if ((((foo > 0) && (foo == myfoo)) || (foo == 0))
            && (((bar > 0) && (bar == mybar)) || (bar == 0))
            && (((foobar > 0) && (foobar == myfoobar)) || (foobar == 0))
            && (((foofoo != null) && (foofoo.equals(myfoofoo))) || (foofoo == null))
            && (((barbar != null) && (mybarbarlist.contains(barbar))) || (barbar == null))
            && (((foobarfoobar != null) && (foobarfoobar
                    .equals(myfoobarfoobar))) || (foobarfoobar == null)))
        validate = true;
    return validate;
}

public static void main(String[] args) {

    Valid valid = new Valid();

    // valid.foo = 1;
    // valid.bar = 1;
    // valid.foobar = 1;
    // valid.foofoo = "1";
    // valid.barbar = "1";
    // valid.foobarfoobar = "1";

    // valid.myfoo = 1;
    // valid.mybar = 1;
    // valid.myfoobar = 1;
    // valid.myfoofoo = "1";
    // valid.mybarbarlist.add("1");
    // valid.myfoobarfoobar = "1";

    System.out.println(valid.isValid());
}
}

2 个答案:

答案 0 :(得分:3)

我首先给每个子表达式赋予有意义的名称,然后将结果分配给变量,然后做一个&amp;&amp;检查变量之间。这将大大提高可读性。

你的条件似乎都有

形式

(X != null && X == value) || X == null

可以使用短路评估简化为

X == null || X == value

因为如果X == null评估为true,那么它不需要检查右侧,或者X == null评估为false并且需要检查右侧是否已经知道它不为空,所以你不要不需要在右侧的表达式中检查null。

将两者结合起来就可以得到这样的结果:

public boolean isValid() {

    validate = false;

    boolean fooCond = (foo == 0) || (foo == myfoo);
    boolean barCond = (bar == 0) || (bar == mybar);
    boolean foobarCond = (foobar == 0) || (foobar == myfoobar);
    boolean foofooCond = (foofoo == null) || foofoo.equals(myfoofoo);
    boolean barbarCond = (barbar == null) || mybarbarlist.contains(barbar);
    boolean foobarfoobarCond = (foobarfoobar == null) || foobarfoobar.equals(myfoobarfoobar);

    if (fooCond
          && barCond
          && foobarCond
          && foofooCond;
          && barbarCond
          && foobarfoobarCond) {
        validate = true;
    }

    return validate;
}

修改

对于您正在检查

的表达式,完全不起作用
((foo > 0) && (foo == myfoo)) || (foo == 0)

因为如果foo < 0它返回false。如果你的意思是

((foo > 0) && (foo == myfoo)) || (foo <= 0)

然后这个方法按照书面形式工作。

答案 1 :(得分:2)

我建议阅读有关布尔代数和简化布尔表达式的内容。有多种方法可以做到这一点,无论是卡诺图还是仅仅使用代数定律。

您可以查看this,它可以让您基本了解它的含义。关于你的代码,我建议记下一个真值表,并在你的方法返回true时计算出真值。从那里抓住你当前的等式并尽可能地简化它


还要举例说明简化的工作原理: enter image description here

  

XOR B = A&amp; !B OR!A&amp;乙

左侧如果是右侧的简化表达


有关对您有帮助的法律列表,请查看Boolean Algebra Laws