(condition1 || condition2) && (condition1 != condition2)
(при этом нет разницы, применяются ли побитовые операторы & и |, или же логические && и ||)
Часто указывают на сходство между сложением по модулю 2 и конструкцией «либо … либо …» в естественном языке. Составное утверждение «либо A, либо B» считается истинным, когда истинно либо A, либо B, но не оба сразу; в противном случае составное утверждение ложно. Это в точности соответствует определению операции в булевой алгебре, если «истину» обозначать как 1, а «ложь» как 0.
Эту операцию нередко сравнивают с дизъюнкцией потому, что они очень похожи по свойствам, и обе имеют сходство с союзом «или» в повседневной речи.
Операция исключает последний вариант («оба сразу») и по этой причине называется исключающим «ИЛИ». Операция включает последний вариант («оба сразу») и по этой причине иногда называется включающим «ИЛИ». Неоднозначность естественного языка заключается в том, что союз «или» может применяться в обоих случаях.
Wikimedia Foundation. 2010.
Игры ⚽ Поможем решить контрольную работу
Есть целая куча популярных задач для собеседований, которые можно решить одним из двух способов: или логичным применением стандартных структур данных и алгоритмов, или использованием некоторых свойств XOR сложным для понимания способом.
= value return resultС первого взгляда на код алгоритм понять сложно. Однако если знать, как работает трюк с XOR, то он становится довольно тривиальным. По-моему, именно поэтому не стоит ждать такого решения на собеседованиях: оно требует знания очень специфичного трюка, но почти никакого алгоритмического мышления.
Прежде чем мы перейдём к следующему способу применения, я сделаю пару замечаний.
Хоть мы пока работали только с целыми числами от 1 до n, это необязательно. На самом деле, предыдущий алгоритм работает в любой ситуации, где есть (1) некоторое множество потенциальных элементов и (2) множество действительно встречающихся элементов. Эти множества могут отличаться только одним отсутствующим элементом. Это замечательно сработало для целых чисел, потому что множество потенциальных элементов соответствует элементам от 1 до n.
Можно придумать способы применения, где элементы не являются целыми числами от 1 до n:
Person
и нам нужно найти Person
, отсутствующего в списке значенийЕсли алгоритм по-прежнему кажется вам непостижимым и магическим (надеюсь, это не так), то может быть полезным подумать, как достичь того же результата при помощи арифметических операторов.
На самом деле всё довольно просто:def find_missing(A, n): result = 0 # Add all the values from 1 to n for value in range(1, n + 1): result += value # Subtract all values in the given array for value in A: result -= value return result
Мы складываем все потенциальные целые числа, а затем вычитаем те, которые встречаются на самом деле. Это решение не такое красивое, потому что придётся обрабатывать переполнения, а также потому что тип элементов должен поддерживать +
, -
с определёнными свойствами. Однако здесь используется та же логика взаимного уничтожения элементов, потому что они встречаются определённое количество раз (один раз как положительное, другой — как отрицательное).
И вот здесь всё становится интереснее: мы можем применить точно такое же решение к похожей задаче с собеседования:
Дан массив A
из n + 1 целых чисел, находящихся в интервале от 1 до n. Все числа встречаются ровно один раз, за исключением одного числа, которое повторяется. Найти это повторяющееся число.
Давайте подумаем, что произойдёт, если мы просто применим алгоритм из предыдущего решения. Мы получим последовательность операторов XOR, в которой элементы встречаются следующим образом:
Как и ранее, все повторяющиеся элементы взаимно уничтожаются. Это означает, что у нас осталось именно то, что мы ищем: элемент, повторяющийся в исходном массиве. 0 = x
Все остальные элементы взаимно уничтожаются, потому что встречаются ровно два раза.
Оказывается, мы можем расширить возможности алгоритма. Рассмотрим чуть более сложную задачу:
Дан массив A
из n — 2 целых чисел, находящихся в интервале от 1 до n. Все числа встречаются ровно один раз, за исключением двух отсутствующих чисел. Найти эти два отсутствующих числа.
Как и ранее, задача полностью эквивалентна поиску двух повторяющихся чисел.
Как вы наверно догадались, мы будем придерживаться того, что сработало раньше, и начнём точно так же: рассмотрим, что произойдёт, если использовать предыдущий алгоритм с XOR. Если мы его применим, то получим последовательность операторов XOR, в которой все элементы взаимно уничтожают друг друга, за исключением тех, которые мы ищем.
i
, в которой u
и v
должны различаться. Затем мы разделим A
, а также числа от 1 до n в соответствии с этим битом. В результате мы получим два сегмента, каждый из которых содержит два множества:0
i
-тый бит равен 0
i
-тый бит равен 0
1
i
-тый бит равен 1
i
-тый бит равен 1
Так как u
и v
различаются в позиции i
, то мы знаем, что они должны быть в разных сегментах.
Далее мы можем использовать ещё одно сделанное ранее открытие:
Хоть пока мы работали только с целыми числами от 1 до n, это необязательно. На самом деле, предыдущий алгоритм работает в любой ситуации, где есть (1) некоторое множество потенциальных элементов и (2) множество действительно встречающихся элементов. Эти множества могут отличаться только одним отсутствующим (или повторяющимся) элементом.
u
, применив этот принцип к одному из сегментов и найдя отсутствующий элемент, а затем найти v
, применив его к другому сегменту.На самом деле это очень удобный способ решения задачи: по сути, мы сводим данную новую задачу к более общей версии решённой ранее задачи.
Можно попробовать пойти ещё дальше и попытаться решить задачу с тремя и более отсутствующими значениями. Я не особо это обдумывал, но считаю, что на этом наши успехи с XOR закончатся. Если отсутствует (или повторяется) больше двух элементов, то анализ отдельных битов выполнить не удастся, поскольку существует множество сочетаний для результатов в виде 0
и 1
.
Следовательно, задача требует более сложных решений, больше не использующих XOR.
Как говорилось выше, наверно, не стоит давать такие задачи на собеседованиях. Для их решения нужно знать не сразу понятный трюк, но если он известен, то решать больше практически нечего (возможно, за исключением способа применения 4). Едва ли таким образом кандидат продемонстрирует алгоритмическое мышление (кроме навыков упрощения) и здесь не особо получится использовать структуры данных.
Однако здорово было выяснить, как этот трюк работает. Похоже, XOR обладает идеально подходящими для этой задачи свойствами. Кроме того, есть некая красота в том, что нечто столь фундаментальное, как XOR, можно использовать для создания описанных в статье алгоритмов.
VDSina предлагает виртуальные серверы на Linux и Windows — выбирайте одну из предустановленных ОС, либо устанавливайте из своего образа.
XOR в криптографии В этом примере используется XOR и один и тот же «секретный ключ» для шифрования и дешифрования. Хотя можно использовать логику XOR, алгоритмы секретного ключа намного сложнее, чем это. См. алгоритм шифрования.
Реклама
{X-html заменен}
Выбор редакции
ЭТО ОПРЕДЕЛЕНИЕ ПРЕДНАЗНАЧЕНО ТОЛЬКО ДЛЯ ЛИЧНОГО ИСПОЛЬЗОВАНИЯ. Любое другое воспроизведение требует разрешения.Информационные бюллетени PCMag
Информационные бюллетени PCMag
Наши лучшие истории в вашем почтовом ящике
Подпишитесь на PCMag
PCMag. com является ведущим авторитетом в области технологий, предоставляющим независимые лабораторные обзоры новейших продуктов и услуг. Наш экспертный отраслевой анализ и практические решения помогут вам принимать более обоснованные решения о покупке и получать больше от технологий.
Как мы тестируем Редакционные принципы
(Открывается в новом окне)
PCMag поддерживает Group Black и ее миссию по увеличению разнообразия голосов в СМИ и прав собственности на СМИ.
© 1996-2023 Ziff Davis, LLC., компания Ziff Davis. Все права защищены.
PCMag, PCMag.com и PC Magazine входят в число зарегистрированных на федеральном уровне товарных знаков Ziff Davis и не могут использоваться третьими лицами без явного разрешения. Отображение сторонних товарных знаков и торговых наименований на этом сайте не обязательно указывает на какую-либо принадлежность или поддержку PCMag. Если вы нажмете на партнерскую ссылку и купите продукт или услугу, этот продавец может заплатить нам комиссию.
Отрицательное число хранится в двоичном виде как в дополнении до двух . В дополнении до 2 крайняя левая битовая позиция зарезервирована для знака значения (положительного или отрицательного) и не влияет на значение числа.
В Python отрицательные числа записываются с ведущей единицей вместо ведущей нуль. Итак, если вы используете только 8 бит для ваших 9-3) .
- Двоичное представление
-5
можно рассматривать как1000...101
и- Двоичное представление
-3
можно рассматривать как1000...011
.Здесь
...
обозначают все 0, количество которых зависит от битов, используемых для представления (32-бит, 64-бит и т. д.).1
в MSB ( старший бит ) означает, что число, представленное двоичным представлением, отрицательно. Операция XOR будет выполняться для всех битов, как обычно. 9-3 = 6Так как MSB становится равным 0 после операции XOR, то полученное число является положительным числом. Точно так же для всех отрицательных чисел мы рассматриваем их представление в двоичном формате, используя 2 в дополнении (одно из наиболее часто используемых) и выполняем простое XOR над их двоичным представлением.