Я знаю, что это старая тема, но я наткнулся на тот же вопрос и обнаружил небольшую хитрость. Если у вас есть n бит, вместо того, чтобы требовать n бит операций (например, ответ Джеспера), вы можете сделать это с помощью log2 (n) число операций:
Предположим, что y в начале программы равен x XOR (x / 2), вы можете выполнить следующую C-программу:
INPUT : y
int i, x;
x = y;
for (i = 1; i < n; i <<= 1)
x ^= x >> i;
OUTPUT : x
и вот вам решение.
- «>>» - операция сдвига вправо. Например, число 13, 1101 в двоичном формате, если смещено на 1 справа, станет 110 в двоичном, таким образом, 13 >> 1 = 6. x >> i эквивалентно x / 2 ^ i (деление на целые числа, конечно)
- «<<» - операция сдвига левого бита (i << = 1 эквивалентно i * = 2) </li>
Почему это работает? Давайте возьмем в качестве примера n = 5 битов и начнем с y = b4 b3 b2 b1 b0 (в двоичном виде: в следующем x также записано в двоичном формате, но i записано в десятичном виде)
x = b4 b3 b2 b1 b0
x >> 1 = b4 b3 b2 b1, поэтому мы имеем
x = b4 b3 b2 b1 b0 XOR b3 b2 b1 b0 = b4 (b3 ^ b4) (b2 ^ b3) (b1 ^ b2) (b0 ^ b1)
x >> 2 = b4 (b3 ^ b4) (b2 ^ b3), поэтому мы имеем
x = b4 (b3 ^ b4) (b2 ^ b3) (b1 ^ b2) (b0 ^ b1) XOR b4 (b3 ^ b4) (b2 ^ b3) = b4 (b3 ^ b4) (b2 ^ b3 ^ b4) ( b1 ^ b2 ^ b3 ^ b4) (b0 ^ b1 ^ b2 ^ b3)
x >> 4 = b4, поэтому мы имеем
x = b4 (b3 ^ b4) (b2 ^ b3 ^ b4) (b1 ^ b2 ^ b3 ^ b4) (b0 ^ b1 ^ b2 ^ b3) XOR b4 = b4 (b3 ^ b4) (b2 ^ b3 ^ b4) ( b1 ^ b2 ^ b3 ^ b4) (b0 ^ b1 ^ b2 ^ b3 ^ b4)
- Тогда i = 8, что больше 5, мы выходим из цикла.
И у нас есть желаемый вывод.
Цикл имеет log2 (n) итераций, потому что i начинается с 1 и умножается на 2 на каждом шаге, поэтому, чтобы i достиг n, мы должны сделать это log2 (n) раз.