Напишите функцию, меняющую местами значения переменных, не используя временные переменные
48К открытий49К показов
Это классическая задача, которую любят предлагать на собеседованиях, и она достаточно проста. Пусть a0 — это исходное значение a, а b0 — исходное значение b. Обозначим diff разницу а0 - b0.
Давайте покажем взаимное расположение всех этих значений на числовой оси для случая, когда a > b:
Присвоим а значение diff. Если сложить значение b и diff, то мы получим a0 (результат следует сохранить в b). Теперь у нас b = а0 и a = diff. Все, что нам остается сделать, — присвоить b значение а0 - diff, а это значение представляет собой b - a.
Приведенный далее код реализует этот алгоритм:
Можно решить эту задачу с помощью битовой манипуляции. Такой подход позволит нам работать с разными типами данных, а не только с integer.
Этот код использует операцию XOR. Проще всего понять, как работает код, взглянув на два бита — р и q. Давайте обозначим как р0 и q0 исходные значения.
Если мы сможем поменять местами два бита, то алгоритм будет работать правильно. Давайте рассмотрим работу алгоритма пошагово:
- p = p0^q0 /* 0 если р0 = q0, 1 если р0 != q0 */
- q = p^q0 /* равно значению р0 */
- 3. p = p^q /* равно значению q0 */
В строке 1 выполняется операция p = p0^q0, результатом которой будет 0, если p0 = q0, и 1, если p0 != q0.
В строке 2 выполняется операция q = p^q0. Давайте проанализируем оба возможных значения p. Так как мы хотим поменять местами значения p и q, в результате должен получиться 0:
p = 0: в этом случаеp0 = q0, так как нам нужно вернутьp0илиq0.XORлюбого значения с 0 всегда дает исходное значение, поэтому результатом этой операции будетq0(илиp0).p = 1: в этом случаеp0 != q0. Нам нужно получить 1, еслиq0 = 0, и 0, еслиp0 = 1. Именно такой результат получается при операцииXORлюбого значения с 1.
В строке 3 выполняется операция p = p^q. Давайте рассмотрим оба значения p. В результате мы хотим получить q0. Обратите внимание, что q в настоящий момент равно p0, поэтому на самом деле выполняется операция p^p0.
p = 0: так какp0 = q0, мы хотим вернутьp0илиq0. Выполняя0^p0, мы вернемp0(q0).p = 1: выполняется операция1^p0. В результате мы получаем инверсиюp0, что нам и нужно, так какp0 != q0.
Остается только присвоить p значение q0, a q — значение р0. Мы удостоверились, что наш алгоритме корректно меняет местами каждый бит, а значит, результат будет правильным.
Разбор взят из перевода книги Г. Лакман Макдауэлл и предназначен исключительно для ознакомления.Если он вам понравился, то рекомендуем купить книгу «Карьера программиста. Как устроиться на работу в Google, Microsoft или другую ведущую IT-компанию».
48К открытий49К показов

