Проверьте, верно ли хотя бы два из трех логических значений

569
задан 7 revs, 6 users 49% 25 January 2013 в 22:30
поделиться

48 ответов

Если цель состоит в том, чтобы вернуть поразрядное значение два из трех для трех операндов, арифметический и итерационный подходы, как правило, будут относительно неэффективными. На многих архитектурах ЦП хорошей формой будет "return ((a | b) & c) | (a & b);". Это требует четырех логических операций. На машинах с одним аккумулятором (обычно в небольших встроенных системах) это может принимать в общей сложности семь инструкций на байт. Форма "return (a & b) | (a & c) | (b & c);" возможно, выглядит лучше, но для этого потребовалось бы пять логических операций или девять инструкций на байт на машине с одним аккумулятором.

Между прочим, в КМОП-логике для вычисления «не два из трех» требуется двенадцать транзисторов (для сравнения: инвертору требуется два, для двухвходовой И-НЕ или ИЛИ-ИЛИ - четыре, а для трехвходовой И-НЕ или ИЛИ-ИЛИ - шесть) .

2
ответ дан 22 November 2019 в 22:09
поделиться

Вычислено с помощью таблицы истинности:

return (a & b) | (c & (a ^ b));
3
ответ дан 22 November 2019 в 22:09
поделиться

Этот вид читается лучше:

if (a) {
    return b || c;
} 
else {
    return b && c;
}
3
ответ дан 22 November 2019 в 22:09
поделиться

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

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

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

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

2
ответ дан 22 November 2019 в 22:09
поделиться

2 и 3 в заданном вопросе явно магические числа. «Правильный» ответ будет зависеть от того, пытался ли интервьюер понять вашу логику (и я не думаю, что ответ pdox может быть лучше в этом отношении) или ваше понимание архитектурных проблем.

Я бы предпочел решение map-reduce, которое будет принимать любые списки с любыми произвольными условиями.

2
ответ дан 22 November 2019 в 22:09
поделиться
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;
}
2
ответ дан 22 November 2019 в 22:09
поделиться

К вашему сведению, это всего лишь бит переноса полного сумматора. В аппаратном обеспечении вы можете использовать логические усилия для определения оптимальной схемы на основе различных логических выражений. Я предполагаю, что традиционное решение XOR потребует больше усилий, чем менее сжатое выражение, представленное на плакате.

2
ответ дан 22 November 2019 в 22:09
поделиться
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);
}
0
ответ дан 22 November 2019 в 22:09
поделиться

Моя первая мысль, когда я увидел вопрос, была:

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".

3
ответ дан 22 November 2019 в 22:09
поделиться

X = OR (a + b, c)

a b c X

1 1 0 1

0 0 1 1

0 1 1 1

2
ответ дан 22 November 2019 в 22:09
поделиться

Я нашел это решение.

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    bool result = !(a ^ b ^ c) && !(!a & !b & !c) || (a & b & c);
    return result;
}
2
ответ дан 22 November 2019 в 22:09
поделиться

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

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

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

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
ответ дан 22 November 2019 в 22:09
поделиться

В C # , сразу в голову:

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

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

Вызов будет выглядеть следующим образом:

lol( 2, true, true, false );

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

2
ответ дан 22 November 2019 в 22:09
поделиться

Я не видел, чтобы другие указывали на одну вещь: стандартная вещь, которую нужно сделать в разделе «напишите мне код» на собеседовании - это сказать: «Не могли бы вы это исправить? " или "Вы полностью довольны этим" или "Оптимизировано ли это настолько, насколько это возможно?" когда вы говорите, что закончили. Возможно, вы слышали «как бы вы это улучшили» или «это можно улучшить; как?». В этом случае изменение if (x) вернет true; else return false; идиома просто return x - это улучшение, но имейте в виду, что иногда они просто хотят увидеть, как вы отреагируете на вопрос. Я слышал, что некоторые интервьюеры будут настаивать на том, что в идеальном коде есть изъян, просто чтобы посмотреть, как вы с ним справляетесь.

2
ответ дан 22 November 2019 в 22:09
поделиться

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

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

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

или если ((A && (B || C)) || C) { вернуть истину; } еще вернуть ложь;

2
ответ дан 22 November 2019 в 22:09
поделиться

C:

if (!!a + !!b + !!c >= 2)
1
ответ дан 22 November 2019 в 22:09
поделиться

Моя первая мысль была

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

но для простоты чтения мне больше понравилось предложенное вами решение a+b+c>=2

-7
ответ дан 22 November 2019 в 22:09
поделиться

Я считаю, что использование простых логических операторов (a || b) && (b || c) нормально и проще.

Вы можете поменять местами любую из 3 букв с любыми двумя другими, и это останется тем же выражением.

-4
ответ дан 22 November 2019 в 22:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: