如何检查布尔表达式的所有可能性?

时间:2013-12-29 04:59:28

标签: java computer-science

我目前正试图弄清楚如何检查布尔表达式!b && (c || !d)!(b || !c && d的所有可能性,对布尔b c有八种可能的分配, d我需要确定哪个组合会产生(!b && (c || !d)) != (!(b || !c && d)我当前的代码是:

public static void Main(String[] args)
{
    java.util.Random randy = new java.util.Random();
    boolean expression1 = false;
    boolean expression2 = false;
    boolean[] b = {true, false};
    boolean[] c = {true, false};
    boolean[] d = {true, false};
    int B = 0;
    int C = 0;
    int D = 0;

    while(expression1 == expression2)
    {
        B = randy.nextInt(2);
        C = randy.nextInt(2);
        D = randy.nextInt(2);
        expression1 = !b[B] && (c[C] || !d[D]);
        expression2 = !(b[B] || !c[C] && d[D]);
    }

    if(expression1 != expression2)
    {
        JOptionPane.showMessageDialog(null, "b: " + b + "c: " + c + "d: " + d);
    }
}

然而它似乎没有做到这一点。所以我的问题是我如何能够找出布尔表达式的所有可能性,然后将它们相互比较以查看它们是否彼此不相等。

4 个答案:

答案 0 :(得分:2)

只有八种可能性,因此将它们全部枚举起来并不难。有点像这样(没有经过远程测试):

static boolean toBoolean(int n) {
    if(n==0) {return false; }
    return true;
}
...
for(int b_int=0; b_int<2; b_int++) {
    for(int c_int=0; c_int<2; c_int++) {
        for(int d_int=0; d_int<2; d_int++) {
            boolean b = toBoolean(b_int);
            boolean c = toBoolean(c_int);
            boolean d = toBoolean(d_int);
            boolean expr1 = whatever;
            boolean expr2 = whatever else;
            if(expr1 != expr2) {
                // Eureka! signal success
            }
         }
     }
}

只要你强行解决问题,就要考虑枚举而不是随机测试,特别是如果问题的可能性很小。也就是说,您可以尝试在表达式上使用de Morgan's laws。如果我自己做得对,你会找到一些有趣的东西。

答案 1 :(得分:2)

两个表达式都是相同的,因此它们将始终彼此相等。让我们对第二个表达式进行一些转换:

!(b || !c && d)   # original expression
!(b || (!c && d)) # && has precedence over ||
!b && !(!c && d)  # negate the whole expression
!b && (c || !d)   # negate the right most expression

我们刚刚获得与第一个相同的表达式,因此(!b && (c || !d)) != (!(b || !c && d))将始终评估为false。

答案 2 :(得分:2)

您当前的方法存在的问题是,您正在使用随机化来获取所有变量的所有组合,但这并不能保证您将获得所有变量。

另一个问题似乎在于你的代码片段的逻辑:如果在任何时候expression1 != expression2你将离开while循环并且if语句将为true,它将打印消息对话框然后程序将退出。由于你使用的是random,每次使用不同的值时都会获得相同的值,但是你总会获得一种可能性。

一种方法是创建一个真值表,其中包含所涉及变量的真实性的所有组合,并且每次都测试您的表达式。例如:

private static void compareExpressions() {
    final int NUMBER_OF_VARIABLES = 3;
    final int NUMBER_OF_ROWS = (int) Math.pow(2, NUMBER_OF_VARIABLES);

    boolean values[] = new boolean[NUMBER_OF_VARIABLES];
    boolean expression1, expression2;

    // Build a truth table

    for(int i = 0; i < NUMBER_OF_ROWS; i++) {
        for(int j = NUMBER_OF_VARIABLES - 1, k = 0; j >= 0; j--, k++) {
            values[k] = (i / (int) Math.pow(2, j)) % 2 == 0 ? false : true;
        }

        // Compare what you need and show results for each row in the truth table
        expression1 = !values[0] && (values[1] || !values[2]);
        expression2 = !(values[0] || !values[1] && values[2]);

        if(expression1 != expression2) {
            System.out.println("b: " + values[0] + " c: " + values[1] + " d: " + values[2]);
        }
    }   
}

使用这种方法可以创建任意大小的真值表但由于values[]数组中的“未命名”变量或者如果有变量,变量数量会增加,因此会变得繁琐且容易出错不同的表达。

不幸的是,解决这个问题需要表达式的解析器以及存储变量的更好方法(例如,Map<String, Boolean>)。

答案 3 :(得分:0)

您可以使用嵌套循环检查所有可能的组合。

for(int i=0;i<2;i++){
    for(int j=0;j<2;j++){
        for(int k=0;k<2;k++){
            //Check b[i] c[j] d[k] for your condition and handle accordingly
        }
    }
}