ตรวจสอบว่าอย่างน้อยสองในสามบูลีนเป็นจริง


579

ผู้สัมภาษณ์เมื่อเร็ว ๆ นี้ได้ถามคำถามนี้กับฉัน: เมื่อกำหนดตัวแปรบูลีนสามตัวคือ a, b และ c ให้คืนค่าจริงถ้าอย่างน้อยสองจากสามตัวนั้นเป็นจริง

วิธีการแก้ปัญหาของฉันเป็นดังนี้:

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

เขากล่าวว่าสิ่งนี้สามารถปรับปรุงได้มากขึ้น แต่อย่างไร


170
อินไลน์คำสั่งการส่งคืน
Finglas

45
ดูเหมือนสัมภาษณ์ "ผู้ที่มีไอคิวสูงที่สุด" ฉันจะล้มเหลว
Chris Dutrow

79
atLeastTwo(iWantYou, iNeedYou, imEverGonnaLoveYou)
Andrew Grimm

92
ทำไมผู้คนถึงตอบคำถามที่ไม่สำคัญมากที่สุด?
BlueRaja - Danny Pflughoeft

46
คำถามทั่วไปและเข้าใจง่ายจะได้รับคะแนนเสียงมากขึ้น คำถามที่เฉพาะเจาะจงมากและไม่ใช่ด้านเทคนิค
Jay

คำตอบ:


820

แทนที่จะเขียน:

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);
}

มันทดสอบaและbว่าครั้งเดียวและอย่างcมากที่สุดครั้งเดียว

อ้างอิง


144
1: วิธีการแก้ปัญหาที่น่าจะปริศนา แต่หวังว่าเราไม่เห็นอะไรเช่นนี้ในโลกจริง :)
จูเลียต

124
@ จูเลียต: ฉันไม่รู้ฉันคิดว่าถ้านี่เป็นข้อกำหนดของโลกแห่งความจริง (ด้วยชื่อตัวแปรจริง) มันจะอ่านได้ค่อนข้างดี พิจารณาreturn hasGoodAttendance ? (passedCoursework || passed Exam) : (passedCoursework && passedExam)ว่าดูดีสำหรับฉัน
Andrzej Doyle

18
ฉันไม่คิดว่ารูปลักษณ์ที่ไม่ดีแต่ถ้าต้องการประสิทธิภาพที่จะเข้าใจ "อย่างน้อยสอง" atLeastTwo(hasgoodAttendance, passedCoursework, passedExam)ผมคิดว่ามันจะง่ายต่อการอ่าน ความคิดของ "อย่างน้อย 2 bools เป็นจริง" เป็นเรื่องทั่วไปพอที่จะได้รับหน้าที่ของมัน
Ken

17
@Lese: การขอรหัสที่เหมาะที่สุดในการสัมภาษณ์แบบตัวต่อตัวนั้นเป็นไปไม่ได้และฉันก็กล้าพูดไม่ได้ การปรับให้เหมาะสมแบบ Micro เมื่อขับเคลื่อนด้วยความต้องการนั้นถูกชี้นำโดยผลลัพธ์การทำโปรไฟล์แบบรันไทม์ไม่ใช่สัญชาตญาณของมนุษย์ (ซึ่งรู้กันว่าแย่มาก) คุณสามารถถามผู้ให้สัมภาษณ์ถึงกระบวนการที่คุณควรปรับปรุงเรื่องนี้ต่อไป นั่นสำคัญกว่าผลลัพธ์เอง
polygenelubricants

17
ผู้ประกอบการที่ประกอบไปด้วยสำนวนเป็นเรื่องธรรมดาที่คุณควรอ่านได้ หากคุณไม่สามารถอ่านได้คุณควรศึกษาจนกว่าคุณจะสามารถ การใช้ตัวดำเนินการประกอบไปด้วยไม่ใช่สิ่งที่ฉันคิดว่า "ฉลาด" ในแง่เสื่อมเสีย แต่ใช่ฉันจะใส่นี่เป็นส่วนหนึ่งของการเรียกเมธอดหากคุณมักใช้ตรรกะ "อย่างน้อยสอง"
Stephen P

493

เพียงเพื่อประโยชน์ของการใช้แฮคเกอร์เพื่อตอบปัญหาที่ค่อนข้างตรงไปตรงมา ...

return a ^ b ? c : a

159
ว้าวโซลูชันที่ยอดเยี่ยม แต่สำหรับฉันเวอร์ชันฤvertedษีมันเข้าใจง่ายกว่า: a == b? a: c
Rotsor

5
a ^ b? c: a ^ b? c: a ^ b? c: a
alexanderpas

4
เย้ .. แฮคเกอร์กดได้แย่มากและคุณไม่ค่อยได้ใช้มัน
EightyOne Unite

18
@ Stimul8d อาจเป็นเพราะสำหรับบูลีนมันก็เหมือนกับ! = แต่อ่านได้น้อยลง? หาว่าเป็นช่วงเวลาที่ eureka สำหรับฉัน ...
ทิคฮอน Jelvis

2
ฉันชอบรูปแบบไบนารีอย่างหมดจด: return ((a ^ b) & c) | (a & b) มันเป็นสาขาที่น้อยกว่า (เร็วกว่า) และอ่านง่าย: (a หรือ b เป็นจริงและ c เป็นจริง) หรือ (a และ b เป็นจริงทั้งคู่) โปรดทราบว่า (a | b) และ (a ^ b) ทั้งคู่ทำงานร่วมกับสูตรนี้
flanglet

217

ทำไมไม่ใช้มันอย่างแท้จริง? :)

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

ใน C คุณสามารถเขียนได้a+b+c >= 2(หรือ!!a+!!b+!!c >= 2ปลอดภัยมาก)

ในการตอบสนองต่อ เปรียบเทียบ TubeBeerของ java bytecode นี่คือการทดสอบประสิทธิภาพอย่างง่าย:

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);
        }
    }
}

สิ่งนี้จะพิมพ์สิ่งต่อไปนี้บนเครื่องของฉัน (ใช้งาน Ubuntu บน Intel Core 2 + sun java 1.6.0_15-b03 พร้อม HotSpot Server VM (14.1-b02, โหมดผสม)):

การวนซ้ำครั้งแรกและครั้งที่สอง:

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:

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มันจะช้าลงเกือบ 100 เท่า แต่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

4
a+b+c >= 2: มันไม่ทำงานกับเนกาทีฟใช่มั้ย คุณอาจจะต้องทำ!!aสิ่งนี้ฉันไม่แน่ใจ
polygenelubricants

8
<s> -1 คุณไม่ควรทำเช่นนั้นสำหรับ C. คุณไม่รู้ว่าคุณค่าของความจริงคืออะไร (มันอาจจะง่ายเท่ากับ -1) </s> จริงๆแล้วฉันเดาว่า C99 รวมอยู่ในมาตรฐานที่จริงกำหนดไว้เป็น 1 แต่ ฉันยังคงไม่ทำเช่นนี้
Mark Peters

1
เป็นไปได้ไหมถ้าข้อมูลของคุณเป็นผลมาจากการดำเนินการบูลีน และเป็นไปได้สำหรับ "bool" ชนิดใน C ++ หรือไม่
Rotsor

2
@Rotsor: ไม่มีใครพูดว่าการป้อนข้อมูลจะต้องเป็นผลมาจากการดำเนินการบูลีน แม้ไม่มีเชิงลบคุณกำลังเล่นด้วยไฟราวกับว่าคุณกำหนดเป็น 2 เงื่อนไขของคุณจะมีผลบวกปลอม แต่ฉันไม่สนใจเรื่องนั้นมากเท่าที่ฉันไม่ชอบความคิดที่จะผสมบูลีนเข้ากับคณิตศาสตร์ โซลูชัน Java ของคุณชัดเจนว่าไม่ต้องพึ่งพาการแปลงที่เหมาะสมจากบูลีนเป็นประเภทจำนวนเต็ม
Mark Peters

7
ระมัดระวังด้วย microbenchmarks: java.sun.com/docs/hotspot/HotSpotFAQ.html#benchmarking_simple
BalusC

143

คำถามประเภทนี้สามารถแก้ไขได้ด้วยแผนที่ Karnaugh :

      | 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

10
@Justin, แผนที่ Karnaugh ลดจำนวนการดำเนินการทางตรรกะจาก 3 ANDs และ 2 ORs เป็น 2 ANDs และ 2 ORs @ แจ็คขอบคุณที่เตือนฉันถึงการมีอยู่ของแผนที่ Karnaugh
Tachy

14
+1 สำหรับสิ่งใหม่ สเป็คการใช้งานต่อไปของฉันจะมี K-map ไม่ว่ามันจะต้องการหรือมัน
Justin R.

2
บางทีความสามารถในการอ่านที่ไม่ดีอาจถูกชดเชยโดย (1) ตารางที่เหมาะสมในความคิดเห็นและ (2) การทดสอบหน่วยที่เหมาะสม ... +1 สำหรับสิ่งที่มีประโยชน์ที่เรียนรู้ที่โรงเรียน
moala

140

การอ่านควรเป็นเป้าหมาย คนที่อ่านรหัสจะต้องเข้าใจเจตนาของคุณทันที นี่คือทางออกของฉัน

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

return howManyBooleansAreTrue >= 2;

21
ฉันเห็นด้วยกับสถานที่ตั้ง แต่ (& & b) || (b&&C) || (&&&) สามารถอ่านได้มากกว่าโซลูชัน IMHO ของคุณ
Adrian Grigore

62
อืมตอนนี้ฉันต้องการรุ่น "สองจากสี่บูลีน" ... เวอร์ชั่นของ danatel นั้นง่ายกว่ามากตอนนี้
Arafangion

6
หรือใน Scala:Seq(true, true, false).map(if (_) 1 else 0).sum >= 2
retronym

5
@retronym: อืมไม่มี วิธี Java ใช้งานได้ดีใน Scala และสามารถอ่านได้และมีประสิทธิภาพมากขึ้น
Seun Osewa

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

คำอธิบาย:

หากa==bทั้งสองเป็นจริงหรือทั้งสองเป็นเท็จ หากทั้งคู่เป็นจริงเราจะพบบูลีนที่แท้จริงของเราสองคนและสามารถกลับมาจริงaได้ หากทั้งสองเป็นเท็จมีไม่สามารถเป็นสอง booleans จริงแม้ว่าcจะเป็นจริงเพื่อให้เรากลับเท็จ (โดยกลับa) นั่นเป็น(a==b) ? aส่วนหนึ่ง เกี่ยวกับ: cอะไร ดีถ้าa==bเป็นเท็จแล้วว่าหนึ่งในaหรือbต้องเป็นจริงเพื่อให้เราได้พบความจริงบูลแรกและสิ่งเดียวที่เหลือว่าเรื่องคือถ้าcยังเป็นจริงเพื่อให้เรากลับมาcเป็นคำตอบ


8
c ไม่เคยผ่านการทดสอบ ... สุดยอด!
CurtainDog

ใช้ความสัมพันธ์แบบสกรรมกริยาของความเสมอภาคและความจริงที่ว่าบูลีนอาจเป็นจริงหรือเท็จ +1
Christophe Roussy

3
สง่างามมาก! ฉันต้องตรวจสอบด้วยปากกาและกระดาษเพื่อเชื่อว่า :) คุณรุ่งโรจน์ถึงคุณ!
เอเดรีย

3
ฉันคิดเกี่ยวกับเรื่องนี้ว่า "ถ้าaและbเห็นด้วยพวกเขามีคะแนนเสียงส่วนใหญ่ดังนั้นไปกับสิ่งที่มันเป็นอย่างอื่นพวกเขาไม่เห็นด้วยดังนั้นcการลงคะแนนตัดสินใจ"
Ben Millwood

34

คุณไม่จำเป็นต้องใช้รูปแบบการลัดวงจรของตัวดำเนินการ

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

วิธีนี้จะใช้การดำเนินการทางตรรกะในจำนวนเท่ากันกับเวอร์ชั่นของคุณ


11
ทำไมคุณต้องการบังคับให้มีการประเมิน 5 ครั้งเมื่อ 1 ทำได้ มันไม่ได้ทำการดำเนินการทางตรรกะในจำนวนที่เท่ากันจริง ๆ ในความเป็นจริงก็จะมักจะดำเนินการมากขึ้น
Mark Peters

2
ฉันคิดว่าการผสมเลขฐานสองและเลขคณิตแบบบูลเป็นความคิดที่ไม่ดี มันเป็นเหมือนประแจขันสกรูในผนังด้วยประแจ ที่แย่ที่สุดคือมีความหมายต่างกัน
Peter Tillemans

12
@ Mark - มันอาจเร็วกว่า ... ขึ้นอยู่กับผลของการคาดคะเนสาขาที่ไม่ถูกต้องบนไพพ์ไลน์ของ CPU อย่างไรก็ตามเป็นการดีที่สุดที่จะปล่อยให้ micro-optimization ไปยังคอมไพเลอร์ JIT
Stephen C

4
การทำบางสิ่งเช่นนี้ใน Java (หรือภาษาอื่น ๆ ) ... โดยมีข้อแม้สองข้อ: 1) จะต้องเร็วขึ้น (ในกรณีนี้ฉันเชื่อว่ามันคือดูคำตอบที่สองของฉัน) 2) เร็วกว่ามาก (ไม่แน่ใจว่าเป็นหรือไม่) 3) เอกสารสำคัญที่สุดเนื่องจากเป็น "คี่" ตราบใดที่มันมีจุดประสงค์และมีการบันทึกไว้ก็เป็นเรื่องดีที่จะ "ทำลายกฎ" เมื่อมีเหตุผล
TofuBeer

11
@Peter Tillemans ไม่มีการผสมกับตัวดำเนินการไบนารีใน Java เหล่านี้เป็นตัวดำเนินการบูลีน
starblue

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
ว้าวฉันไม่เคยเห็นวิธีทดสอบอย่างเต็มที่มาก่อนเลย
Rotsor

51
ฉันเองพบว่ารหัสนี้อันยิ่งใหญ่ด้วยเหตุผลมากมาย ฉันจะไม่ลงคะแนน แต่ถ้าฉันเคยเห็นสิ่งนี้ในรหัสการผลิตฉันจะสาปแช่ง การดำเนินการบูลีนที่ง่ายมากไม่จำเป็นต้องมีความซับซ้อนเช่นนี้
CaptainCasey

10
ฉันสนใจที่จะทราบเหตุผลของคุณมากที่สุด @CaptainCasey ฉันคิดว่านี่เป็นรหัสที่ดีทีเดียว มีฟังก์ชั่นทั่วไปที่ดีที่เข้าใจง่ายตรวจสอบง่ายและฟังก์ชั่นเฉพาะที่ใช้ประโยชน์จากมันง่ายต่อการเข้าใจและตรวจสอบ ในโลกแห่งความเป็นจริงฉันจะทำให้พวกเขาเป็นที่รู้จักและทำให้พวกเขาอยู่ในชั้นเรียนอื่น นอกจากนั้นฉันจะใส่รหัสนี้อย่างมีความสุขในการผลิต โอ้ - ใช่ - ฉันจะเปลี่ยนชื่อ countBooleans () เป็น countTrue ()
Carl Manaster

5
ถ้ามันไม่เกี่ยวกับประสิทธิภาพโซลูชันนี้ดูเกือบจะสมบูรณ์แบบสำหรับฉัน: อ่านและขยายได้ง่ายมาก นั่นคือสิ่งที่ var-args ทำขึ้นมา
atamanroman

7
คนอะไรกันเนี่ย? นี่เป็นรหัสที่ชัดเจนและผ่านการทดสอบเป็นอย่างดีและเหตุผลเดียวที่ดูเหมือนว่ามีมากคือเพราะมันมีการทดสอบ +++ จะโหวตขึ้นอีกครั้ง
Christoffer Hammarström

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

2
นี่เป็นทางออกที่หรูหราที่สุดในความคิดของฉัน
Torbjørn Kristoffersen

9
ความผิดพลาด Rookie แม้ว่าค่าบูลีนจะไม่ใช่ 0 ซึ่งไม่ได้หมายความว่ามันจะเป็น 1 เสมอ
tomdemuyt

13
ยกเว้นว่าแท็กในโพสต์ระบุว่า "Java" และคุณไม่สามารถเขียน "a + b + c" เมื่อกำหนดเป็น booleans ใน Java
Jay

ในการทำงานใน Java return ((a?1:0) + (b?1:0) + (c?1:0)) >= 2ก็จะต้องมีการ
David R Tribble

Duh ฉันลงคะแนนให้เพราะฉันคิดว่ามันเป็นคำถาม C ++ ... ทำไมฉันถึงอ่านคำถาม java : /
Carlo Wood


15

มันขึ้นอยู่กับสิ่งที่คุณหมายถึงโดย "ปรับปรุง":

ชัดเจน?

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

Terser?

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.

สิ่งใดที่ "ปรับปรุง" ขึ้นอยู่กับสถานการณ์เป็นอย่างมาก


14

นี่คือการใช้งานอื่นโดยใช้แผนที่ / ลด สิ่งนี้ปรับขนาดได้ดีถึงพันล้าน booleans ©ในสภาพแวดล้อมแบบกระจาย ใช้ MongoDB:

สร้างฐานข้อมูลvaluesของ booleans:

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

สร้างแผนที่ลดฟังก์ชั่น:

แก้ไข : ฉันชอบคำตอบของ CurtainDog เกี่ยวกับการมี 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;
}

ใช้แผนที่ / ลด:

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;
}

@ Anurag: เท่าที่ฉันรัก M / R และการเปิดเผยที่ Google เพิ่งมอบให้กับมัน (แม้ว่าจะไม่ใช่ M / R ที่แท้จริงจาก FP) ฉันก็มักจะเรียก bullsh! t ในคำตอบของคุณ มีเส้นรหัสเป็นพันล้านและพันล้านเส้นที่แสดง "สิ่ง" ในโลกแห่งความเป็นจริง [TM] ซึ่งไม่มีแผนที่เส้นเดียว / ลดการใช้ มีคนตอบคำถามดังกล่าวกับนี้ถูกตั้งค่าสถานะแน่นอนในหนังสือของฉันเป็น: "พยายามที่จะเล่น smartie ว่า" ไม่พูดถึงผู้สัมภาษณ์ส่วนใหญ่จะไม่สามารถบอกได้ว่าคุณกำลังพยายามที่จะพล่ามพวกเขาหรือไม่เพราะพวกเขาไม่เคยเขียนโปรแกรมเดียวโดยใช้ M / R ในอาชีพของพวกเขา
ไวยากรณ์ T3rr0r

2
@Syntax - ทุกคนมีสิทธิ์ที่จะแสดงความคิดเห็น คำตอบของฉันคืออีกหนึ่งวิธีในการดูปัญหา แน่นอนว่ามันฟังดูเหมือนเกินจริงสำหรับค่าบูลีน 3 ค่า แต่นั่นไม่ได้หมายความว่าฉันกำลังพยายามจะเป็นกางเกงที่ฉลาด นี่เป็นวิธีการทั่วไปในการแก้ปัญหาที่ทุกคนใช้ - แยกปัญหาออกเป็นชิ้นเล็ก ๆ นั่นเป็นวิธีการอุปนัยเชิงคณิตศาสตร์ว่าอัลกอริทึมแบบเรียกซ้ำส่วนใหญ่ทำงานอย่างไรและนั่นเป็นวิธีที่คนทั่วไปแก้ปัญหา
Anurag

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> 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
}

คุณจะเห็นว่า?: คนที่ดีกว่ารุ่นเดิมที่แก้ไขแล้วเล็กน้อย สิ่งที่ดีที่สุดคือสิ่งที่หลีกเลี่ยงการแตกแขนงโดยสิ้นเชิง นั่นเป็นสิ่งที่ดีจากมุมมองของคำสั่งที่น้อยลง (ในกรณีส่วนใหญ่) และดีกว่าสำหรับส่วนการทำนายสาขาของ CPU เนื่องจากการเดาผิดในการทำนายสาขาอาจทำให้ CPU หยุดทำงาน

ฉันจะบอกว่าคนที่มีประสิทธิภาพมากที่สุดคือคนที่มาจากดวงจันทร์โดยรวม จะใช้คำแนะนำน้อยที่สุดโดยเฉลี่ยและลดโอกาสในการขายแผงใน CPU

เพื่อให้แน่ใจว่า 100% คุณจะต้องค้นหาค่าใช้จ่าย (ในรอบ CPU) สำหรับแต่ละคำสั่งซึ่งน่าเสียดายที่ไม่มีให้ใช้งาน (คุณจะต้องดูแหล่งสัญญาณสำหรับฮอตสปอตแล้วจึงระบุผู้จำหน่ายซีพียูในเวลานั้น นำมาสำหรับการเรียนการสอนที่สร้างขึ้นแต่ละ)

ดูคำตอบล่าสุดโดย Rotsor สำหรับการวิเคราะห์รันไทม์ของรหัส


5
คุณแค่ดูรหัสไบต์เท่านั้น สำหรับสิ่งที่คุณรู้ JIT จะนำรุ่นที่มีสาขาในไบต์และเปลี่ยนเป็นรุ่นที่ไม่มีสาขาในรหัสเนทีฟ แต่มีแนวโน้มที่จะคิดว่าสาขาย่อยในรหัสไบต์จะดีกว่า
David Conrad

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


+1 @Loadmaster ฉันขอโทษ แต่คุณผิด! นี่คือคำตอบที่รวบรัดที่สุดที่นี่ (เช่นแสดงสั้น ๆ และชัดเจน);)
Ash

Micro-เพิ่มประสิทธิภาพ: ++nจะเร็วกว่าเพราะคุณจะต้องสร้างสำเนาอีกก่อนที่จะทำเพิ่มขึ้นn++
M. Mimpen

@ M.Mimpen: สำหรับวัตถุคลาสเท่านั้น สำหรับประเภทพื้นฐาน (เช่นnด้านบน) คอมไพเลอร์ที่เหมาะสมจะรวบรวม++การทำงานแต่ละรายการลงในคำสั่ง CPU เดียวไม่ว่าจะเป็นการโพสต์ก่อนหรือหลัง
David R Tribble

12

วิธีอื่นในการทำเช่นนี้ แต่ไม่ใช่วิธีที่ดีมาก:

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

Booleanค่าแฮชโค้ดได้รับการแก้ไขที่ 1231 สำหรับความจริงและ 1237 สำหรับดังนั้นเท็จอาจมีการใช้อย่างเท่าเทียมกัน<= 3699


1
หรือ (a? 1: 0) + (b? 1: 0) + (c? 1: 0)> = 2
Peter Lawrey

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));
}

แต่การปรับปรุงเหล่านั้นเล็กน้อย


10

ฉันไม่ชอบ ternary ( return a ? (b || c) : (b && c);จากคำตอบยอดนิยม) และฉันไม่คิดว่าฉันเคยเห็นใครพูดถึงมัน มันเขียนแบบนี้:

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

8

ในClojure :

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

การใช้งาน:

(at-least 2 true false true)

2
+1 เวอร์ชันทั่วไปที่ยอดเยี่ยมแสดงถึงพลังของ Lisps ขอบคุณ
dsmith

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;
}

ข้อได้เปรียบของมันคือเมื่อถึงจำนวนที่คุณต้องการ ดังนั้นหากนี่คือ "อย่างน้อย 2 จาก 1,000,000 ค่านี้เป็นจริง" ซึ่งทั้งสองอย่างแรกเป็นจริงแล้วมันควรจะเร็วกว่าโซลูชัน "ปกติ" บางตัว


นั่นน่าจะเป็น: ถ้า (++ counter == howMany) แทนที่จะเป็นการเพิ่มและการตรวจสอบแยกต่างหาก
Joe Enos

2
หรือสั้นกว่านี้: ถ้า (b && (++ counter == howMany))
Joe Enos

1
ฉันจะทำboolean ... boolValuesมันง่ายกว่าที่จะโทร แต่ก็ยังคงจัดลำดับ
Stephen

ฉันไม่ทันสมัยกับ Java ของฉัน - ไม่รู้ว่ามีอยู่จริง ชนิดของไวยากรณ์ที่แปลก แต่มีประโยชน์ - ทุกครั้งที่ฉันจะทำใน C # (คำหลัก params) และมันทำให้สิ่งต่าง ๆ ดีกว่าที่จะเรียก หรือฉันไม่รู้เกี่ยวกับ Java แต่ใน. NET อาร์เรย์และคอลเลกชันทั้งหมดใช้ IEnumerable <T> ดังนั้นฉันอาจจะใช้สิ่งที่เทียบเท่าของ Java
Joe Enos

ประสิทธิภาพของสิ่งนี้เปรียบเทียบกับตัวอย่าง 2of3 อย่างไร กลับมา? (b || c): (b && c);
เลนสคอ

6

เราสามารถแปลง bools เป็นจำนวนเต็มและทำการตรวจสอบง่าย ๆ นี้:

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

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);

แต่ตอนนี้มันไม่ตลกอีกแล้ว


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

มีหลายวิธีที่จะทำ ...


3
ดูเหมือน C # สิ่งนี้ควรถูกกล่าวถึงเช่นนี้ในคำตอบเนื่องจากคำถามนี้มีเป้าหมายเป็นจาวา :)
BalusC

5

สารละลาย AC

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;
}

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

ไม่เห็นคำตอบของ Suvega ก่อนที่จะโพสต์สิ่งนี้เหมือนกัน
Kevin

มันใช้งานได้จริงเหรอ? ฉันถือว่านี่คือ PHP แต่ฉันไม่สามารถเข้าถึงได้ แต่ฉันจะถามคุณว่าจะเกิดอะไรขึ้นถ้า $ a เป็น 0
Mark Edgar

@ Mark มันใช้งานไม่ได้จริงถ้า $ a เท่ากับ 0 นั่นเป็นการควบคุม ขอบคุณสำหรับการชี้ให้เห็นว่า :)
Kevin

4

วิธีที่ง่ายที่สุด (IMO) ที่ไม่สับสนและอ่านง่าย:

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

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

ฟังก์ชั่นมันเหมือนกัน วากยสัมพันธ์มันทำให้ง่ายต่อการอ่านสำหรับผู้ที่ไม่คุ้นเคยกับการใช้ตัวดำเนินการตามเงื่อนไขเครื่องหมายคำถาม ฉันยินดีที่จะเดิมพันผู้คนจำนวนมากรู้วิธีใช้ตัวดำเนินการ AND และ OR มากกว่าจำนวนคนที่รู้วิธีใช้ตัวดำเนินการตามเงื่อนไขเครื่องหมายคำถาม คำถามเดิมถามสำหรับ "คำตอบที่ดีขึ้น" .. คำตอบที่ยอมรับนั้นทำให้คำตอบง่ายขึ้น แต่ทำให้เกิดคำถามที่น่าสนใจมากขึ้นว่าใครจะพิจารณาการปรับปรุง คุณโปรแกรมสำหรับการอ่านสากลหรือเพื่อความง่าย? ให้ฉันนี้คือการปรับปรุงกว่าคำตอบที่ได้รับการยอมรับ :)
abelito

การตั้งค่าส่วนตัว สำหรับฉันมันเป็นวิธีที่ง่ายต่อการเข้าใจผู้ประกอบการที่สะอาดกว่าโซลูชันนี้
โก้

1
ใช่แล้วฉันเห็นปัญหานี้และสงสัยว่าทำไมไม่มีใครพูดถึงวิธีแก้ปัญหานี้ ถ้าคุณเขียนตรรกะของ OP เป็นพีชคณิตแบบบูลคุณจะได้ A B + A C + B C ซึ่งมีการปฏิบัติการห้าอย่าง โดยคุณสมบัติการเชื่อมโยงคุณสามารถเขียน A * (B + C) + B C ซึ่งมีสี่การดำเนินงาน
Vivian River

มันเหมือนกับคำตอบของแจ็ค (19 มิ.ย. ) (C && (A || B)) || (A && B)เพิ่งเปลี่ยน * ตัวแปร
`

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;
}

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 นั้นเป็นภาพรวมที่เร็วที่สุด (บนแล็ปท็อป HP / Intel ของฉัน)



3

เขาอาจจะไม่ได้มองหาอะไรที่ซับซ้อนเช่นผู้ให้บริการเปรียบเทียบระดับบิต (โดยปกติจะไม่ซับซ้อน แต่กับบูลีนมันแปลกมากที่จะใช้ตัวดำเนินการระดับบิต) หรือสิ่งที่เป็นวงเวียนมากเช่นการแปลงเป็น int และรวมพวกเขา

วิธีที่ตรงและเป็นธรรมชาติที่สุดในการแก้ปัญหานี้คือการแสดงออกเช่นนี้:

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

วางไว้ในฟังก์ชั่นหากคุณต้องการ แต่มันไม่ซับซ้อนมาก การแก้ปัญหามีความรัดกุมและมีเหตุผลเชิงตรรกะ


3

ใน C:

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

จริงๆแล้วคำตอบนี้ผิด…ควรเป็น> = 2 เนื่องจากคุณต้องการบูลีนจริงอย่างน้อยสองตัวไม่ใช่สองอย่างแน่นอน
Paul Wagland

@ พอล Wagland: ขอบคุณสำหรับการจับ
Matt Joiner

@ergosys: ฉันตอบครั้งที่สองเหรอ?
Matt Joiner
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.