检查三个布尔中至少有两个是否为真

面试官最近问我这个问题:给出三个布尔变量a,b和c,如果三个中至少有两个是真的,则返回true。

我的解决方案是:

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    if ((a && b) || (b && c) || (a && c)) {
        return true;
    }
    else{
        return false;
    }
}

他表示,这可以进一步改善,但如何?


而不是写作:

if (someExpression) {
    return true;
} else {
    return false;
}

写:

return someExpression;

至于表达本身,就像这样:

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    return a ? (b || c) : (b && c);
}

或者这个(无论你发现哪一个更容易理解):

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    return a && (b || c) || (b && c);
}

它测试ab恰好一次,而c最多只测试一次。

参考

  • JLS 15.25有条件的运营商? :

  • 只是为了使用异或来回答一个相对直接的问题...

    return a ^ b ? c : a
    

    为什么不直接实施? :)

    (a?1:0)+(b?1:0)+(c?1:0) >= 2
    

    在C中,你可以写a+b+c >= 2 (或者!!a+!!b+!!c >= 2是非常安全的)。

    为了回应TofuBeer对java字节码的比较,下面是一个简单的性能测试:

    class Main
    {
        static boolean majorityDEAD(boolean a,boolean b,boolean c)
        {
            return a;
        }
    
        static boolean majority1(boolean a,boolean b,boolean c)
        {
            return a&&b || b&&c || a&&c;
        }
    
        static boolean majority2(boolean a,boolean b,boolean c)
        {
            return a ? b||c : b&&c;
        }
    
        static boolean majority3(boolean a,boolean b,boolean c)
        {
            return a&b | b&c | c&a;
        }
    
        static boolean majority4(boolean a,boolean b,boolean c)
        {
            return (a?1:0)+(b?1:0)+(c?1:0) >= 2;
        }
    
        static int loop1(boolean[] data, int i, int sz1, int sz2)
        {
            int sum = 0;
            for(int j=i;j<i+sz1;j++)
            {
                for(int k=j;k<j+sz2;k++)
                {
                    sum += majority1(data[i], data[j], data[k])?1:0; 
                    sum += majority1(data[i], data[k], data[j])?1:0; 
                    sum += majority1(data[j], data[k], data[i])?1:0; 
                    sum += majority1(data[j], data[i], data[k])?1:0; 
                    sum += majority1(data[k], data[i], data[j])?1:0; 
                    sum += majority1(data[k], data[j], data[i])?1:0; 
                }
            }
            return sum;
        }
    
        static int loop2(boolean[] data, int i, int sz1, int sz2)
        {
            int sum = 0;
            for(int j=i;j<i+sz1;j++)
            {
                for(int k=j;k<j+sz2;k++)
                {
                    sum += majority2(data[i], data[j], data[k])?1:0; 
                    sum += majority2(data[i], data[k], data[j])?1:0; 
                    sum += majority2(data[j], data[k], data[i])?1:0; 
                    sum += majority2(data[j], data[i], data[k])?1:0; 
                    sum += majority2(data[k], data[i], data[j])?1:0; 
                    sum += majority2(data[k], data[j], data[i])?1:0; 
                }
            }
            return sum;
        }
    
        static int loop3(boolean[] data, int i, int sz1, int sz2)
        {
            int sum = 0;
            for(int j=i;j<i+sz1;j++)
            {
                for(int k=j;k<j+sz2;k++)
                {
                    sum += majority3(data[i], data[j], data[k])?1:0; 
                    sum += majority3(data[i], data[k], data[j])?1:0; 
                    sum += majority3(data[j], data[k], data[i])?1:0; 
                    sum += majority3(data[j], data[i], data[k])?1:0; 
                    sum += majority3(data[k], data[i], data[j])?1:0; 
                    sum += majority3(data[k], data[j], data[i])?1:0; 
                }
            }
            return sum;
        }
    
        static int loop4(boolean[] data, int i, int sz1, int sz2)
        {
            int sum = 0;
            for(int j=i;j<i+sz1;j++)
            {
                for(int k=j;k<j+sz2;k++)
                {
                    sum += majority4(data[i], data[j], data[k])?1:0; 
                    sum += majority4(data[i], data[k], data[j])?1:0; 
                    sum += majority4(data[j], data[k], data[i])?1:0; 
                    sum += majority4(data[j], data[i], data[k])?1:0; 
                    sum += majority4(data[k], data[i], data[j])?1:0; 
                    sum += majority4(data[k], data[j], data[i])?1:0; 
                }
            }
            return sum;
        }
    
        static int loopDEAD(boolean[] data, int i, int sz1, int sz2)
        {
            int sum = 0;
            for(int j=i;j<i+sz1;j++)
            {
                for(int k=j;k<j+sz2;k++)
                {
                    sum += majorityDEAD(data[i], data[j], data[k])?1:0; 
                    sum += majorityDEAD(data[i], data[k], data[j])?1:0; 
                    sum += majorityDEAD(data[j], data[k], data[i])?1:0; 
                    sum += majorityDEAD(data[j], data[i], data[k])?1:0; 
                    sum += majorityDEAD(data[k], data[i], data[j])?1:0; 
                    sum += majorityDEAD(data[k], data[j], data[i])?1:0; 
                }
            }
            return sum;
        }
    
        static void work()
        {
            boolean [] data = new boolean [10000];
            java.util.Random r = new java.util.Random(0);
            for(int i=0;i<data.length;i++)
                data[i] = r.nextInt(2) > 0;
            long t0,t1,t2,t3,t4,tDEAD;
            int sz1 = 100;
            int sz2 = 100;
            int sum = 0;
    
            t0 = System.currentTimeMillis();
    
            for(int i=0;i<data.length-sz1-sz2;i++)
                sum += loop1(data, i, sz1, sz2);
    
            t1 = System.currentTimeMillis();
    
            for(int i=0;i<data.length-sz1-sz2;i++)
                sum += loop2(data, i, sz1, sz2);
    
            t2 = System.currentTimeMillis();
    
            for(int i=0;i<data.length-sz1-sz2;i++)
                sum += loop3(data, i, sz1, sz2);
    
            t3 = System.currentTimeMillis();
    
            for(int i=0;i<data.length-sz1-sz2;i++)
                sum += loop4(data, i, sz1, sz2);
    
            t4 = System.currentTimeMillis();
    
            for(int i=0;i<data.length-sz1-sz2;i++)
                sum += loopDEAD(data, i, sz1, sz2);
    
            tDEAD = System.currentTimeMillis();
    
            System.out.println("a&&b || b&&c || a&&c : " + (t1-t0) + " ms");
            System.out.println("   a ? b||c : b&&c   : " + (t2-t1) + " ms");
            System.out.println("   a&b | b&c | c&a   : " + (t3-t2) + " ms");
            System.out.println("   a + b + c >= 2    : " + (t4-t3) + " ms");
            System.out.println("       DEAD          : " + (tDEAD-t4) + " ms");
            System.out.println("sum: "+sum);
        }
    
        public static void main(String[] args) throws InterruptedException
        {
            while(true)
            {
                work();
                Thread.sleep(1000);
            }
        }
    }
    

    这将在我的机器上打印以下内容(在带有HotSpot Server VM(14.1-b02,混合模式)的Intel Core 2 + sun java 1.6.0_15-b03上运行Ubuntu):

    第一次和第二次迭代:

    a&&b || b&&c || a&&c : 1740 ms
       a ? b||c : b&&c   : 1690 ms
       a&b | b&c | c&a   : 835 ms
       a + b + c >= 2    : 348 ms
           DEAD          : 169 ms
    sum: 1472612418
    

    后续迭代:

    a&&b || b&&c || a&&c : 1638 ms
       a ? b||c : b&&c   : 1612 ms
       a&b | b&c | c&a   : 779 ms
       a + b + c >= 2    : 905 ms
           DEAD          : 221 ms
    

    我想知道,Java VM会如何降低(a + b + c> = 2)情况下的性能。

    如果我用-client VM开关运行java,会发生什么情况:

    a&&b || b&&c || a&&c : 4034 ms
       a ? b||c : b&&c   : 2215 ms
       a&b | b&c | c&a   : 1347 ms
       a + b + c >= 2    : 6589 ms
           DEAD          : 1016 ms
    

    神秘...

    如果我在GNU Java解释器中运行它,它会慢100倍,但是a&&b || b&&c || a&&c a&&b || b&&c || a&&c a&&b || b&&c || a&&c版本胜出。

    来自Tofubeer的最新代码运行OS X的结果:

    a&&b || b&&c || a&&c : 1358 ms
       a ? b||c : b&&c   : 1187 ms
       a&b | b&c | c&a   : 410 ms
       a + b + c >= 2    : 602 ms
           DEAD          : 161 ms
    

    Paul Wagland使用Mac Java 1.6.0_26-b03-383-11A511的结果

    a&&b || b&&c || a&&c : 394 ms 
       a ? b||c : b&&c   : 435 ms
       a&b | b&c | c&a   : 420 ms
       a + b + c >= 2    : 640 ms
       a ^ b ? c : a     : 571 ms
       a != b ? c : a    : 487 ms
           DEAD          : 170 ms
    
    链接地址: http://www.djcxy.com/p/40237.html

    上一篇: Check if at least two out of three booleans are true

    下一篇: Python integer incrementing with ++