Серый двоичный код Является ли способ выражения двоичных чисел, такие что последовательные числа отличаются ровно 1 цифрой. Например, в нашей обычной бинарной системе номера
- 000
- 001
- 010
- 011
- 100
- 101
- 110
- 111 и так далее
В серых, они:
- 000
- 001
- 011
- 010
- 110
- 111
- 101
- 100 и так далее
В первой системе, когда мы идем от «001 ‘до 010», существует 2 изменения, а именно место для устройства становится «0» от «1», и следующая цифра становится «1» от «0». Но в системе Грей «001» становится «011», где есть только 1 изменение (2-я цифра).
Серые коды используются в коррекции ошибок в связи.
Генерация серых кодов длины n
Есть ли свойство, которую мы можем использовать для легко создания серых кодов данной длины? Да! В нашем предыдущем примере мы создали все серые коды для. Игнорируя наиболее значимый бит ( MSB ), обратите внимание, как 4-е и 5-е номера равны в их первых 2 цифрах, как 3-й и 6, 2-й и 7 и 1-й и 8-й. Последние 4 номера – Отражение из первых 4, если мы игнорируем последнюю цифру. Но последняя цифра 0 для 1-го числа и 1 для последних 4 … У нас есть рекурсивная формулировка.
R (0) = [] (n) + 1R ‘(n) r (n)) Ибо у нас есть пустой список. Для N + 1 мы берем R (N), Prepend 0 ко всем элементам и к этой последовательности, мы добавляем реверс R (N) предложены 1.
Это может быть кратко выражено в Python как:
def gray_code(n): if n <= 0: return [] if n == 1: return ['0', '1'] res = gray_code(n-1) return ['0'+s for s in res] + ['1'+s for s in res[::-1]]
Вышеуказанная функция возвращается в правильном порядке все 2 ^ n серых кодов длины n. Нам пришлось добавить дело для n == 1
Потому что мы рассматриваем цифры как строки, чтобы мы могли подготовить «0» или «1». Как и пустой список, нам нужно еще один случай, когда мы впервые добавляем строки.
Преобразование двоичного номера в серый код
Как мы преобразуем двоичный номер в серый код E.G Что такое серый код, эквивалентен 7 (111 в двоичном)? С нашего предыдущего примера это. Таким образом, нам нужна функция, которая принимает целое число и возвращает эквивалентный код серого как целое число.
Мы можем использовать нашу рекурсивную формулировку более раннего доступа к алгоритму. Пусть ^ a + b. Здесь A – MSB N. G (n) – серый код n. Из нашей более ранней формулы ^ a + g (2 ^ a-1-b) .. Из-за свойства отражения. Таким образом, мы знаем значение G (n) в детской цифре. Мы можем продолжать итерацию, чтобы получить другие цифры g (n).
Наш псевдокод:
def bin_to_gray(n): if n == 0: return 0 if n == 1: return 1 a = MSB(n) # Assume MSB function exists. It finds most significant bit of n b = n - 2**a return 2**a + bin_to_gray(2**a-1-b) from math import log2 as l2 # A simple way to find MSB def MSB(n): return int(l2(n))
Еще более быстрый способ:
Оказывается, что есть еще более быстрый способ получения NT-серого кода из n. XOR N/2
В C, Java или Python, это выражено как:
return n ^ (n >> 1)
Приложение: генерируя все серые коды Knuth Style!
Легендарный Дональд Кнут Использует этот алгоритм для создания всех кортежей в его искусстве компьютерного программирования Vol 4a:
public static void gen_gray_bin_taocp(int n) { boolean p = false; // parity bit byte[] a = new byte[n]; // each bit is an element in this array int j = 0; while (true) { System.out.println(Arrays.toString(a)); // Will print the number in reverse order p = !p; if (p) j = 0; else { j = 1; // Find min j so that a[j-1] = 1 while (j < n) { if (a[j-1] == 1) break; j++; if (j == n) // Termination condition return; } a[j] = (byte) (1-a[j]); // We flip the element at j } }
Оригинал: “https://dev.to/rrampage/algorithms-gray-binary-code—a-different-way-of-ordering-numbers-14e3”