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

时间:2010-06-19 15:46:02

标签: java boolean boolean-logic

一位采访者最近问我这个问题:给定三个布尔变量a,b和c,如果三个中至少有两个为真,则返回true。

我的解决方案如下:

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

他说这可以进一步改善,但是如何?

64 个答案:

答案 0 :(得分:812)

而不是写作:

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

参考

答案 1 :(得分:483)

只是为了使用XOR来回答相对直接的问题......

return a ^ b ? c : a

答案 2 :(得分:212)

为什么不按字面意思实现呢? :)

(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

我想知道,对于(a + b + c&gt; = 2)情况,java VM可以做什么降低性能。

如果我使用-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 Interpreter中运行它,它会慢几百倍,但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

答案 3 :(得分:142)

这类问题可以通过Karnaugh Map来解决:

      | C | !C
------|---|----
 A  B | 1 | 1 
 A !B | 1 | 0
!A !B | 0 | 0
!A  B | 1 | 0

从中推断您需要第一行的组和第一列的两个组,以获得多基因润滑剂的最佳解决方案:

(C && (A || B)) || (A && B)  <---- first row
       ^
       |
   first column without third case

答案 4 :(得分:139)

可读性应该是目标。阅读代码的人必须立即理解您的意图。所以这是我的解决方案。

int howManyBooleansAreTrue =
      (a ? 1 : 0)
    + (b ? 1 : 0)
    + (c ? 1 : 0);

return howManyBooleansAreTrue >= 2;

答案 5 :(得分:133)

return (a==b) ? a : c;

说明:

如果a==b,则两者都为真或两者都为假。如果两者都是真的,我们找到了两个真正的布尔值,并且可以返回true(通过返回a)。如果两者都是假的,即使c为真,也不会有两个真正的布尔值,所以我们返回false(通过返回a)。这是(a==b) ? a部分。那么: c呢?好吧,如果a==b为假,那么ab中只有一个必须为真,所以我们找到了第一个真正的布尔值,唯一重要的是if {{1也是如此,所以我们返回c作为答案。

答案 6 :(得分:34)

您不需要使用运算符的短路形式。

return (a & b) | (b & c) | (c & a);

这将执行与您的版本相同数量的逻辑操作,但是完全无分支。

答案 7 :(得分:27)

这是一种以测试为导向的通用方法。并不像迄今为止提供的大多数解决方案那样“高效”,而是清晰,经过测试,工作和推广。

public class CountBooleansTest extends TestCase {
    public void testThreeFalse() throws Exception {
        assertFalse(atLeastTwoOutOfThree(false, false, false));
    }

    public void testThreeTrue() throws Exception {
        assertTrue(atLeastTwoOutOfThree(true, true, true));
    }

    public void testOnes() throws Exception {
        assertFalse(atLeastTwoOutOfThree(true, false, false));
        assertFalse(atLeastTwoOutOfThree(false, true, false));
        assertFalse(atLeastTwoOutOfThree(false, false, true));
    }

    public void testTwos() throws Exception {
        assertTrue(atLeastTwoOutOfThree(false, true, true));
        assertTrue(atLeastTwoOutOfThree(true, false, true));
        assertTrue(atLeastTwoOutOfThree(true, true, false));
    }

    private static boolean atLeastTwoOutOfThree(boolean b, boolean c, boolean d) {
        return countBooleans(b, c, d) >= 2;
    }

    private static int countBooleans(boolean... bs) {
        int count = 0;
        for (boolean b : bs)
            if (b)
                count++;
        return count;
    }
}

答案 8 :(得分:24)

总结一下。它被称为布尔代数,原因如下:

  0 x 0 = 0
  1 x 0 = 0
  1 x 1 = 1

  0 + 0 = 0
  1 + 0 = 1
  1 + 1 = 0 (+ carry)

如果你查看那里的真值表,你可以看到乘法是布尔值,而且只是加法是xor。

回答你的问题:

return (a + b + c) >= 2

答案 9 :(得分:15)

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

答案 10 :(得分:15)

这取决于你所说的“改进”:

更清晰?

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

更简洁?

boolean moreThanTwo(boolean a, boolean b, boolean c)
{
    return a == b ? a : c;
}

更一般?

boolean moreThanXTrue(int x, boolean[] bs)
{
    int count = 0;

    for(boolean b : bs)
    {
        count += b ? 1 : 0;

        if(count > x) return true;
    }

    return false;
}

更具可扩展性?

boolean moreThanXTrue(int x, boolean[] bs)
{
    int count = 0;

    for(int i < 0; i < bs.length; i++)
    {
        count += bs[i] ? 1 : 0;

        if(count > x) return true;

        int needed = x - count;
        int remaining = bs.length - i;

        if(needed >= remaining) return false;
    }

    return false;
}

更快?

// Only profiling can answer this.

哪一项“改善”在很大程度上取决于具体情况。

答案 11 :(得分:14)

这是使用map / reduce的另一个实现。这在分布式环境中可以很好地扩展到数十亿个布尔 ©。使用MongoDB:

创建布尔数据库values

db.values.insert({value: true});
db.values.insert({value: false});
db.values.insert({value: true});

创建地图,减少功能:

修改:我喜欢CurtainDog's answer关于将map / reduce应用于通用列表,所以这里有一个map函数,它接受一个回调来确定一个值是否应该是否计算。

var mapper = function(shouldInclude) {
    return function() {
        emit(null, shouldInclude(this) ? 1 : 0);
    };
}

var reducer = function(key, values) {
    var sum = 0;
    for(var i = 0; i < values.length; i++) {
        sum += values[i];
    }
    return sum;
}

运行map / reduce:

var result = db.values.mapReduce(mapper(isTrue), reducer).result;

containsMinimum(2, result); // true
containsMinimum(1, result); // false


function isTrue(object) {
    return object.value == true;
}

function containsMinimum(count, resultDoc) {
    var record = db[resultDoc].find().next();
    return record.value >= count;
}

答案 12 :(得分:13)

直接代码的另一个例子:

int  n = 0;
if (a) n++;
if (b) n++;
if (c) n++;
return (n >= 2);

显然,这不是最简洁的代码。

<强>附录

另一个(略微优化)的版本:

int  n = -2;
if (a) n++;
if (b) n++;
if (c) n++;
return (n >= 0);

这可能会稍快一些,假设与0的比较将比使用2的比较使用更快(或可能更少)的代码。

答案 13 :(得分:13)

在这里得到答案(到目前为止):

public class X
{
    static boolean a(final boolean a, final boolean b, final boolean c)
    {
    return ((a && b) || (b && c) || (a && c));
    }

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

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

    static boolean d(final boolean a, final boolean b, final boolean c)
    {
    return ((a?1:0)+(b?1:0)+(c?1:0) >= 2);
    }
}

并通过反编译器运行它们(javap -c X&gt; results.txt):

Compiled from "X.java"
public class X extends java.lang.Object{
public X();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

static boolean a(boolean, boolean, boolean);
  Code:
   0:   iload_0
   1:   ifeq    8
   4:   iload_1
   5:   ifne    24
   8:   iload_1
   9:   ifeq    16
   12:  iload_2
   13:  ifne    24
   16:  iload_0
   17:  ifeq    28
   20:  iload_2
   21:  ifeq    28
   24:  iconst_1
   25:  goto    29
   28:  iconst_0
   29:  ireturn

static boolean b(boolean, boolean, boolean);
  Code:
   0:   iload_0
   1:   ifeq    20
   4:   iload_1
   5:   ifne    12
   8:   iload_2
   9:   ifeq    16
   12:  iconst_1
   13:  goto    33
   16:  iconst_0
   17:  goto    33
   20:  iload_1
   21:  ifeq    32
   24:  iload_2
   25:  ifeq    32
   28:  iconst_1
   29:  goto    33
   32:  iconst_0
   33:  ireturn

static boolean c(boolean, boolean, boolean);
  Code:
   0:   iload_0
   1:   iload_1
   2:   iand
   3:   iload_1
   4:   iload_2
   5:   iand
   6:   ior
   7:   iload_2
   8:   iload_0
   9:   iand
   10:  ior
   11:  ireturn

static boolean d(boolean, boolean, boolean);
  Code:
   0:   iload_0
   1:   ifeq    8
   4:   iconst_1
   5:   goto    9
   8:   iconst_0
   9:   iload_1
   10:  ifeq    17
   13:  iconst_1
   14:  goto    18
   17:  iconst_0
   18:  iadd
   19:  iload_2
   20:  ifeq    27
   23:  iconst_1
   24:  goto    28
   27:  iconst_0
   28:  iadd
   29:  iconst_2
   30:  if_icmplt   37
   33:  iconst_1
   34:  goto    38
   37:  iconst_0
   38:  ireturn
}

你可以看到?:1比原版的固定版本略好一些。最好的是完全避免分支的那个。从较少指令(在大多数情况下)的观点来看这是好的,并且对于CPU的分支预测部分更好,因为分支预测中的错误猜测可能导致CPU停滞。

我认为最有效的一个是整个moonshadow。它平均使用最少的指令,并减少CPU中流水线停顿的可能性。

要100%确定你需要找出每条指令的成本(以CPU周期为单位),遗憾的是这些成本并不容易获得(你必须查看热点的来源,然后是CPU供应商的规格)为每个生成的指令花费的时间)。

请参阅Rotsor的更新答案,了解代码的运行时分析。

答案 14 :(得分:12)

最明显的改进包括:

// There is no point in an else if you already returned.
boolean atLeastTwo(boolean a, boolean b, boolean c) {
    if ((a && b) || (b && c) || (a && c)) {
        return true;
    }
    return false;
}

然后

// There is no point in an if(true) return true otherwise return false.
boolean atLeastTwo(boolean a, boolean b, boolean c) {
    return ((a && b) || (b && c) || (a && c));
}

但这些改进很小。

答案 15 :(得分:12)

另一种方法是做到这一点,但不是一个非常好的方法:

return (Boolean.valueOf(a).hashCode() + Boolean.valueOf(b).hashCode() + Boolean.valueOf(c).hashCode()) < 3705);

Boolean哈希码值固定为1231(对于true)和1237(对于false),因此可能同样使用<= 3699

答案 16 :(得分:10)

我不喜欢三元(顶部答案中的return a ? (b || c) : (b && c);),我认为我没见过有人提过它。它是这样写的:

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

答案 17 :(得分:8)

Clojure中:

(defn at-least [n & bools]
  (>= (count (filter true? bools)) n)

用法:

(at-least 2 true false true)

答案 18 :(得分:6)

我们可以将bool转换为整数并执行这个简单的检查:

(int(a) + int(b) + int(c)) >= 2

答案 19 :(得分:6)

由于没有说明代码应该如何改进,我将努力通过使代码更有趣来改进代码。这是我的解决方案:

boolean atLeastTwo(boolean t, boolean f, boolean True) {
    boolean False = True;
    if ((t || f) && (True || False)) 
        return "answer" != "42";
    if (t && f) 
        return !"France".contains("Paris");
    if (False == True) 
        return true == false;
    return Math.random() > 0.5;
}

如果有人想知道这段代码是否有效,这里是使用相同逻辑的简化:

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    if ((a || b) && (c)) 
        return true;
    if (a && b) 
        return true;
    if (true) 
        return false;
    // The last line is a red herring, as it will never be reached:
    return Math.random() > 0.5; 

}

这可以归结为以下内容:

return ((a || b) && (c)) || (a && b);

但现在再也不好笑了。

答案 20 :(得分:6)

我认为我还没有看到这个解决方案:

boolean atLeast(int howMany, boolean[] boolValues) {
  // check params for valid values

  int counter = 0;
  for (boolean b : boolValues) {
    if (b) {
      counter++;

      if (counter == howMany) {
        return true;
      }
    }
  }
  return false;
}

它的优点是,一旦达到你想要的数量,它就会中断。因此,如果这是“这1,000,000个值中至少有2个是真的”,前两个实际上是真的,那么它应该比一些更“正常”的解决方案更快。

答案 21 :(得分:5)

C解决方案。

int two(int a, int b, int c) {
  return !a + !b + !c < 2;
}

或者您可能更喜欢:

int two(int a, int b, int c) {
  return !!a + !!b + !!c >= 2;
}

答案 22 :(得分:5)

Function ReturnTrueIfTwoIsTrue(bool val1, val2, val3))
{
     return (System.Convert.ToInt16(val1) +
             System.Convert.ToInt16(val2) +
             System.Convert.ToInt16(val3)) > 1;
}

执行此操作的方法太多了......

答案 23 :(得分:4)

return 1 << $a << $b << $c >= 1 << 2;

答案 24 :(得分:4)

字面解释适用于所有主要语言:

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

但我可能会让人们更容易阅读,并且可以扩展到三个以上 - 许多程序员似乎忘记了这一点:

boolean testBooleans(Array bools)
{
     int minTrue = ceil(bools.length * .5);
     int trueCount = 0;

     for(int i = 0; i < bools.length; i++)
     {
          if(bools[i])
          {
               trueCount++;
          }
     }
     return trueCount >= minTrue;
}

答案 25 :(得分:4)

最简单的方法(IMO)不会让人感到困惑和易读:

// Three booleans, check if two or more are true

return ( a && ( b || c ) ) || ( b && c );

答案 26 :(得分:4)

作为@TofuBeer TofuBeer优秀帖子的补充,请考虑@pdox pdox的回答:

static boolean five(final boolean a, final boolean b, final boolean c)
{
    return a == b ? a : c;
}

还要考虑“javap -c”给出的反汇编版本:

static boolean five(boolean, boolean, boolean);
  Code:
    0:    iload_0
    1:    iload_1
    2:    if_icmpne    9
    5:    iload_0
    6:    goto    10
    9:    iload_2
   10:    ireturn

pdox的答案编译为比以前任何答案更少的字节代码。它的执行时间与其他时间相比如何?

one                5242 ms
two                6318 ms
three (moonshadow) 3806 ms
four               7192 ms
five  (pdox)       3650 ms

至少在我的电脑上,pdox的答案比@moonshadow moonshadow的答案略快,使得pdox的整体速度最快(在我的惠普/英特尔笔记本电脑上)。

答案 27 :(得分:3)

在C:

return !!a + !!b + !!c >= 2;

答案 28 :(得分:3)

应该是:

(a || b && c) && (b || c && a)

此外,如果true自动转换为1false自动转换为0

(a + b*c) * (b + c*a) > 0

答案 29 :(得分:3)

他可能不会像寻找比特运算符那样复杂(通常不会使用布尔运算,使用按位运算符非常奇怪)或者像转换为int并将它们相加的非常迂回的东西。

解决这个问题的最直接和最自然的方法是使用这样的表达式:

a ? (b || c): (b && c)

如果你愿意,可以把它放在一个函数中,但它不是很复杂。该解决方案在逻辑上简洁有效。

答案 30 :(得分:3)

当我看到这个问题时,我的第一个想法是:

int count=0;
if (a)
    ++count;
if (b)
    ++count;
if (c)
    ++count;
return count>=2;

在看到其他帖子后,我承认

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

更优雅。我想知道相对运行时间是什么。

无论如何,我认为这种解决方案比

的解决方案要好得多
return a&b | b&c | a&c;
变种因为更容易扩展。如果以后我们添加必须测试的第四个变量怎么办?如果在运行时确定变量的数量,并且我们传递了一组未知大小的布尔值,该怎么办?依赖于计数的解决方案比依赖列出每种可能组合的解决方案更容易扩展。此外,在列出所有可能的组合时,我怀疑犯错误要容易得多。就像尝试编写“任意3个4”的代码一样,并确保你既不会错过也不会重复任何内容。现在尝试“任意5个7”。

答案 31 :(得分:3)

在Ruby中:

[a, b, c].count { |x| x } >= 2

可以在JavaVM上的JRuby中运行。 ; - )

答案 32 :(得分:3)

通过真值表计算:

return (a & b) | (c & (a ^ b));

答案 33 :(得分:3)

这种阅读效果更好:

if (a) {
    return b || c;
} 
else {
    return b && c;
}

答案 34 :(得分:2)

让三个布尔值为A,B和C ....

你可以使用k-MAP并附带一个布尔表达式......

在这种情况下,布尔表达式将是A(B + C)+ C

或if((A&amp;&amp;(B || C))|| C)  { 返回true; } 其他 返回false;

答案 35 :(得分:2)

不是在性能上下文,而是良好的代码(可重用的可扩展和可读代码)

     static boolean trueBooleans (int howMany,boolean ... bools)
     {
      int total = 0;

      for (boolean b:bools)
        if (b && (++total == howMany)) return true;


      return false;
    }

在编写Java时,我很谦虚,轻松处理意外更改,没有重复代码比简洁(脚本语言域)或快速程序更重要。

答案 36 :(得分:2)

三元运算符使得书呆子流动,但它们可能令人困惑(使代码不易维护,从而增加了错误注入的可能性)。 Jeff Attwood很好地说here

  

这是一个完美的交易示例   一次完全毫无意义   写入时间可以节省数十个   阅读时间理解惩罚 - 它   让我思考。

避免使用三元运算符,我创建了以下函数:

function atLeastTwoTrue($a, $b, $c) {
        $count = 0;

        if ($a) { $count++; }
        if ($b) { $count++; }
        if ($c) { $count++; }

        if ($count >= 2) {
                return true;
        } else {
                return false;
        }
}

这和其他一些解决方案一样酷吗?不。它更容易理解吗?是。这会导致更易维护,更少错误的代码吗?是。

答案 37 :(得分:2)

如果(a||b) && (a||c) - Java,使用三个比较而不是OP的六个。

错了,我应该早点检查一下。

答案 38 :(得分:2)

此问题的非简化解决方案是:

a'bc + abc' + abc + ab'c

使用K-Maps减少,得到:

bc + ab + ac

可以通过使用独占或a'bc和abc'minterms并结合abc和ab'c minterms来进一步减少这种情况:

b(a ^ c) + ac

答案 39 :(得分:2)

使用Java 8,我真的更喜欢这样的东西:

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    return Stream.of(a, b, c).filter(active -> active).count() >= 2;
}

答案 40 :(得分:2)

绝对是一个问题,更多的是关于你如何解决问题/思考而不是你的实际编码能力。

稍微粗略的版本可能是

  

返回((a ^ b)&amp;&amp;(b ^ c))^ b

但就像之前的一张海报所说的那样,如果我在我正在制作的任何代码中看到这个,那么有人会得到满满的。 :)

答案 41 :(得分:2)

X = OR(a + b,c)

a b c X

1 1 0 1

0 0 1 1

0 1 1 1

答案 42 :(得分:2)

如果目标是为三个操作数返回三位二进制值,则算术和迭代方法往往相对无效。在许多CPU架构中,一个好的形式是“返回((a | b)&amp; c)|(a&amp; b);”。这需要四个布尔运算。在单累加器机器上(在小型嵌入式系统中很常见),每个字节总共需要七个指令。形式“return(a&amp; b)|(a&amp; c)|(b&amp; c);”可能看起来更漂亮,但它需要五个布尔运算,或单个累加器机器上每个字节九个指令。

顺便提一下,在CMOS逻辑中,计算“不是三分之二”需要十二个晶体管(为了比较,一个逆变器需要两个,一个双输入NAND或NOR需要四个,三输入NAND或NOR需要六个)

答案 43 :(得分:2)

我找到了这个解决方案。

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    bool result = !(a ^ b ^ c) && !(!a & !b & !c) || (a & b & c);
    return result;
}

答案 44 :(得分:2)

提出的问题中的2和3绝对是神奇的。 “正确”的答案将取决于面试官是否试图掌握布尔逻辑(我不认为pdox的答案可能会在这方面被击败)或者你对架构问题的理解。

我倾向于使用map-reduce解决方案,它可以接受任意条件下的任何类型的列表。

答案 45 :(得分:2)

问题的最佳答案应该是“作为一名员工,重要的是我编写它以便我的意思明确,同时在表现必要时保持效率。”这是我写的方式:

function atLeastTwoAreTrue(a, b, c) {
    return (a && b) || (b && c) || (a && c);
}

实际上,测试是如此的设计,如果你用一个简单的评论来容纳它,那么写一个最快,最神秘的方法是完全可以接受的。但是,总的来说,在这个单行世界中,我们需要更多可读代码。 : - )

答案 46 :(得分:2)

int count=0;

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    if (a)
        count++;
    if (b)
        count++;
    if (c)
        count++;

    if (count>1)
        return true;
    else
        return false;
}

答案 47 :(得分:2)

我没有看到其他人指出的一件事是在求职面试的“请写一些代码”栏目中要做的标准事情就是说“你能改进吗?”或者“你对此完全满意”还是“尽可能优化?”当你说你完成了。你有可能听到“你会如何改进”,因为“这可能会有所改善;怎么样?”。在这种情况下,将if(x) return true; else return false;成语更改为return x只是一种改进 - 但请注意,有时他们只是想看看您对问题的反应。我听说有些采访者会坚持认为完美代码存在缺陷只是为了看你如何应对它。

答案 48 :(得分:2)

C#中,脱离了我的头顶:

public bool lol(int minTrue, params bool[] bools)
{
    return bools.Count( ( b ) => b ) >= minTrue;
}

应该很快。

电话会是这样的:

lol( 2, true, true, false );

这样,你将规则(两个必须为真)留给调用者,而不是将它们嵌入到方法中。

答案 49 :(得分:2)

仅供参考,这只是全加器的结转位。在硬件中,您可以使用逻辑工作来根据不同的布尔表达式确定最佳电路。我猜想传统的XOR解决方案比海报所展示的不太简洁的表达需要更多的努力。

答案 50 :(得分:1)

C:

if (!!a + !!b + !!c >= 2)

答案 51 :(得分:1)

使用Java 8的Stream功能采用另一种方法,对任意数量的任意数量的布尔值进行处理。如果Stream在处理所有元素之前达到极限,则会短路:

public static boolean atLeastTrue(int amount, Boolean ... booleans) {
    return Stream.of(booleans).filter(b -> b).limit(amount).count() == amount;
}

public static void main(String[] args){
    System.out.println("1,2: " + atLeastTrue(1, true, false, true));
    System.out.println("1,1: " + atLeastTrue(1, false, true));
    System.out.println("1,0: " + atLeastTrue(1, false));
    System.out.println("1,1: " + atLeastTrue(1, true, false));
    System.out.println("2,3: " + atLeastTrue(2, true, false, true, true));
    System.out.println("3,2: " + atLeastTrue(3, true, false, true, false));
    System.out.println("3,3: " + atLeastTrue(3, true, true, true, false));
}

输出:

1,2: true
1,1: true
1,0: false
1,1: true
2,3: true
3,2: false
3,3: true

答案 52 :(得分:1)

这个怎么样:

(a - b) ? c : a

答案 53 :(得分:0)

借助算术运算,这很简单。

boolean a = true;
boolean b = false;
boolean c = true;


// Exactly One boolean value true.
if((a?1:0)+(b?1:0)+(c?1:0)==1) 
   return true;
else
   return false;

// Exactly 2 boolean value true.
if((a?1:0)+(b?1:0)+(c?1:0)==2) 
   return true;
else
   return false;

这就是如何增加常量的值来检查有多少布尔值是 true

答案 54 :(得分:0)

另一个:

return a? b||c : b&&c

答案 55 :(得分:0)

public static boolean atLeast(int atLeastToBeTrue, boolean...bools){
    int booleansTrue = 0;
    for(boolean tmp : bools){
        booleansTrue += tmp ? 1 : 0;
    }
    return booleansTrue >= atLeastToBeTrue;
}

您可以从at least a.k.a varargs中选择您想要成功的boolean[]次数: - )

答案 56 :(得分:0)

函数ko返回答案:

static int ho(bool a)
{
    return a ? 1 : 0;
}

static bool ko(bool a, bool b, bool c)
{
    return ho(a) + ho(b) + ho(c) >= 2 ? true : false;
}

答案 57 :(得分:0)

使用三元运算符解决问题的最简单形式是:

return a ? (b ? true : c) : (b ? c : false);

您可能还希望通过使用需求的双重否定来寻找解决方案,也就是说,您需要至少满足一个假值,而不是至少两个真值。

答案 58 :(得分:0)

如果我将布尔值转换为数字,并且如果数字不是2的幂,则它至少有两个真值。

a*4 + b*2 + c*1 = N
return( N != 0 && (N&(N-1)) != 0)

我只是在提供替代方案。

答案 59 :(得分:0)

function atLeastTwoTrue($a, $b, $c) {

  int count = 0;
  count = (a ? count + 1 : count);
  count = (b ? count + 1 : count);
  count = (c ? count + 1 : count);
  return (count >= 2);
}

答案 60 :(得分:0)

在我看来,三分之三是非常随意的数字,并且该函数应该使用任意数字。所以为了回答这个问题,我会编写一个函数,如果数组中的x为真,那将会有效,例如,

bool istrue ( int x, bool[] list)
    y = count true in list
    return y >= x

答案 61 :(得分:-4)

我相信使用普通布尔运算符(a || b)&amp;&amp; (b || c)很好而且更简单。

您可以将3个字母中的任何一个与其他两个字母中的任何一个交换,并且它仍然是相同的表达。

答案 62 :(得分:-6)

我认为最简单的解决方案是:

返回(a&amp;&amp; b)|| ℃;

答案 63 :(得分:-7)

我的第一个想法是

return (a||b)&&(b||c)

但是为了便于阅读,我喜欢提议的a + b + c&gt; = 2解决方案,你们建议更好