Цепные коды
Версия от 02:24, 27 ноября 2010; Ден (обсуждение | вклад)
Цепной код — это код, каждый следующий столбец которого получается из предыдущего циклическим сдвигом вверх.
Алгоритм получения цепного кода для двоичного вектора
- Берем в качестве первого слова слово из n нулей.
- Делаем циклический сдвиг предыдущего слова влево с потерей первого разряда.
- Приписываем к полученному слову в конец единицу. Проверяем, встречалось ли это слово в коде ранее.
- Если нет, то записываем его в код, иначе последнюю единицу заменяем на ноль и записываем слово в код.
- Если получено слово из n нулей, то код полностью записан, иначе возвращаемся к шагу 2
Доказательство корректности
Разобьем доказательство на две части:
- Доказательство того, что одно и то же слово встречается в коде не более одного раза.
- Доказательство того, что код перебирает все возможные слова прежде, чем получит слово из n нулей.
Доказательство первого пункта
Покажем, что в этом алгоритме никогда не будет ситуации, когда нам надо образовать новое слово, а оба возможных вариантов (добавление нуля или единицы) уже были использованы. Рассмотрим первое такое противоречие, то есть уже было два слова, которые начинались таким же набором единиц и нулей и отличались только в последнем разряде. Но они были получены из двух слов, которые отличаются только в первом разряде, значит, мы должны были столкнуться с данной ситуацией на шаг раньше, но мы предполагали, что это первый подобный случай и пришли к противоречию. Следовательно, мы не можем столкнуться с данной ситуацией.
Доказательство второго пункта
Покажем, что невозможно вернуться к слову из всех нулей, пока не переберем все
слов, где n — длина слова. Допустим, мы всё же получили слово из всех нулей раньше, чем перебрали все слова. Тогда разобьём слова, которые не попали в код на две группы: кончающиеся на единицу и кончающиеся на ноль. Докажем, что второй группы группы нет. Рассмотрим слово {abc..yz}0, не попавшее в код, где {abc..yz} — некоторая последовательность единиц и нулей. Заметим, что слово {bc..yz}00 также не в коде. Оно могло быть получено из слов 1{bc..yz}0 и 0{bc..yz}0, одно из которых есть рассматриваемое {abc..yz}0. Но если другое слово и встретилось в коде, то мы бы получили из него {bc..yz}01, следуя алгоритму (причем это слово точно встретится в первый раз). Таким образом, слово {bc..yz}00 точно не в коде. Такую же цепочку рассуждений можно провести и для слова {c..yz}000, и так далее. На n-ом шаге мы бы получили утверждение, что слова из n нулей тоже нет в коде, и пришли бы к противоречию. Заметим, что исходя из третьего и четвертого шагов, все слова вида {abc..yz}1 встречаются строго раньше {abc..yz}0, которые точно записаны в код. Таким образом, слов, не попавших в код, нет.