Проверьте, верно ли хотя бы два из трех логических значений - PullRequest
568 голосов
/ 19 июня 2010

Один из интервьюеров недавно задал мне этот вопрос: при наличии трех логических переменных a, b и c верните true, если хотя бы две из трех верны.

Мое решение следующее:

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

Он сказал, что это можно еще улучшить, но как?

Ответы [ 63 ]

2 голосов
/ 22 июня 2010

В C # , вне макушки моей головы:

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

должно быть довольно быстрым.

Вызов будет выглядеть так:

lol( 2, true, true, false );

Таким образом, вы оставляете правила (два должны быть истинными) до вызывающей стороны, а не встраиваете их в метод.

2 голосов
/ 22 июня 2010

X = OR (a + b, c)

abc X

1 1 0 1

0 0 1 1

0 1 11

2 голосов
/ 21 июня 2010

Тернарные операторы заставляют соков ботаников течь, но они могут сбивать с толку (делая код менее обслуживаемым, увеличивая тем самым возможность внедрения ошибок). Джефф Эттвуд хорошо сказал здесь :

Это прекрасный пример компромисса совершенно бессмысленно один раз экономия времени записи против десятков штрафы за понимание во время чтения Заставляет меня думать.

Избегая троичных операторов, я создал следующую функцию:

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

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

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

Это так же круто, как и некоторые другие решения? Нет. Это легче понять? Да. Приведет ли это к более понятному, менее ошибочному коду? Да.

2 голосов
/ 29 июля 2010

Позвольте трем логическим значениям быть A, B и C ....

Вы можете использовать k-MAP и прийти с логическим выражением ...

В этом случае логическоевыражением будет A (B + C) + C

или if ((A && (B || C)) || C) {return true;} иначе вернуть false;

2 голосов
/ 22 июня 2010

Определенно, это больше вопрос о том, как вы решаете проблемы / думаете, чем о вашей реальной способности к кодированию.

Более краткая версия может быть

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

Но, как сказал предыдущий автор, если бы я видел это в каком-либо коде, над которым я работал, кто-то получал бы заслуженный доход.:)

2 голосов
/ 22 июня 2010

Лучший ответ на вопрос должен звучать так: «Как работник, я должен написать это так, чтобы мое значение было ясным, сохраняя эффективность там, где это необходимо для эффективности». Вот как бы я это написал:

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

На самом деле тест настолько изобретателен, что написание метода, который является самым быстрым и наиболее загадочным из возможных, вполне приемлемо, если вы сопровождаете его простым комментарием. Но, в общем, в этом мире с одной строкой нам нужен более читаемый код в этом мире. : -)

2 голосов
/ 01 февраля 2012

Не в контексте производительности, но хорошего кода (расширяемый и читаемый код, который можно использовать повторно)

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

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


      return false;
    }

По моему скромному мнению, при написании Java проще обрабатывать неожиданные изменения и не дублировать код, чемкраткий (область языков сценариев) или быстрая программа.

2 голосов
/ 15 сентября 2011

Как насчет (a||b) && (a||c) - Java использует три сравнения вместо шести ОП.

Неправильно, я должен был проверить раньше.

2 голосов
/ 12 июля 2011

Неуменьшенное решение этой проблемы:

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

Сокращение с помощью K-Maps дает:

bc + ab + ac

Можно уменьшить это дополнительно, используя эксклюзив или наa'bc и abc 'minterms и объединение abc и ab'c minterms:

b(a ^ c) + ac
2 голосов
/ 10 ноября 2016

В настоящее время с Java 8, я действительно предпочитаю что-то вроде этого:

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