Если у вас нет XOR
, то, конечно, вы можете сделать то же самое с обычной «непроверенной» суммой, то есть суммой 32-битных целых чисел с «циклическим переносом» (без «проверки переполнения», иногда известной как unchecked
контекст).
Это сложение по модулю 2 32 . Я рассмотрю «неподписанный» случай. Если ваш 32-битный int использует дополнение до двух, это то же самое. (Для математика два дополнения до сих пор просто сложение (и умножение) по модулю 2 32 , мы выбираем только другого канонического представителя для каждого класса эквивалентности по модулю 2 32 .)
Если бы у нас было все ненулевые 32-битные целые числа, мы бы получили:
1 + 2 + 3 + … + 4294967295 ≡ 2147483648
Один из способов реализации этого состоит в том, чтобы взять первый и последний члены вместе, они дают ноль (по модулю 2 32 ). Тогда второй член (2
) и второй последний член (4294967294
) также дают ноль. Таким образом, все условия отменяются, кроме среднего (2147483648
), которое затем равно сумме.
Представьте, что из этого равенства вы вычитаете одно из чисел (назовите его x
) с обеих сторон символа ≡
. Отсюда вы видите, что вы нашли пропущенное число, начиная с 2147483648
и вычитая (все еще unchecked
) из этого числа все, что вам дали. Тогда вы получите пропущенный номер:
missingNumber ≡ 2147483648 - x1 - x2 - x3 - … - x4294967294
Конечно, это то же самое, что и решение луны, только что выполненное в кольце целых чисел по модулю 2 32 .
Элегантное решение XOR
(ответ Sykora) также может быть написано таким же образом, и с этим XOR
функционирует как +
и -
одновременно. То есть, если бы у нас было все ненулевые 32-битные целые числа, то
1 XOR 2 XOR 3 XOR … XOR 4294967295 ≡ 0
и затем XOR
с пропущенным номером x
с обеих сторон символа ≡
, чтобы увидеть, что:
missingNumber ≡ x1 XOR x2 XOR x3 XOR … XOR x4294967294