Задача состоит в том, чтобы найти кодовое слово для буквы Н, которое бы удовлетворяло условию префиксного кода (никакое кодовое слово не является началом другого) и минимизировало бы длину закодированного слова ПОРОЛОН.
Сначала определим известные кодовые слова и их длину:
Слово ПОРОЛОН состоит из следующих букв: П, О, Р, О, Л, О, Н.
Известные кодовые слова уже имеют следующие префиксы:
Чтобы код был префиксным, новое кодовое слово для буквы Н не должно начинаться ни с одного из существующих префиксов, и ни один из существующих префиксов не должен начинаться с кодового слова Н.
Рассмотрим возможные короткие кодовые слова для буквы Н, начиная с наименьшей длины:
Если мы назначим Н = 10 (длина 2), то длина слова ПОРОЛОН будет:
Для минимизации общей длины слова ПОРОЛОН, нужно чтобы кодовое слово для буквы О было как можно короче.
Рассмотрим все буквы, которые нужно закодировать: К, Л, М, Н, О, П, Р. Алфавит: {К, Л, М, Н, О, П, Р}.
Известные кодовые слова:
Недостающие буквы: М, Н, О.
Используем построение дерева кодов для наглядности.
Корневой узел:
Узел 0:
Узел 00:
Узел 000:
Узел 1:
Узел 11:
Узел 111:
Теперь нам нужно назначить коды для М, Н, О. При этом Н и О входят в слово ПОРОЛОН.
Наиболее короткие доступные префиксы (не занятые и не являющиеся префиксами других кодов):
Чтобы минимизировать длину слова ПОРОЛОН, нужно назначить наименьшие возможные коды для букв Н и О, а также для М (если он используется в слове). В слове ПОРОЛОН есть буква О, но нет буквы М.
Нам нужны коды для Н и О.
Наиболее короткие свободные коды: 10 (2), 010 (3), 011 (3), 110 (3).
Назначим Н = 10 (длина 2).
Теперь осталось назначить код для О. Из коротких свободных кодов остаются: 010, 011, 110.
Выберем кратчайший из них: 010 (длина 3).
Таким образом, кодовые слова:
Проверим, что это префиксный код:
Значит, назначение О = 010 некорректно, так как 01 (Л) является префиксом 010 (О).
Нужно найти такой набор кодов для М, Н, О, чтобы:
Слово ПОРОЛОН: П(3), О(?), Р(4), О(?), Л(2), О(?), Н(?).
Для минимизации длины, нам нужны как можно более короткие коды для О и Н.
Давайте снова построим дерево и посмотрим на доступные ветви:
0
├─ 00
│ ├─ 000
│ │ └─ 0001 (К)
│ └─ 001 (П)
│ └─ 0010 (свободно)
│ └─ 0011 (свободно)
│ └─ 001X... (свободно)
└─ 01 (Л)
└─ 010 (свободно)
└─ 011 (свободно)
└─ 01X... (свободно)
1
├─ 10 (свободно)
├─ 11
│ ├─ 110 (свободно)
│ └─ 111
│ └─ 1110 (Р)
│ └─ 1111 (свободно)
└─ 11XX... (свободно)
Доступные кратчайшие свободные коды (в порядке возрастания длины и числового значения):
Чтобы минимизировать длину слова ПОРОЛОН, нужно дать кратчайшие коды для О и Н.
Самый короткий свободный код - 10 (длина 2).
Назначим его для Н.
Теперь нам нужен код для О. Из оставшихся коротких свободных кодов:
Если мы назначим О = 010, то код Л (01) станет префиксом кода О (010). Это недопустимо.
Если мы назначим О = 011, то код Л (01) станет префиксом кода О (011). Это недопустимо.
Если мы назначим О = 110, то код Л (01) не будет префиксом. Это допустимо.
Итак, назначим:
Проверим дерево с этим назначением:
0
├─ 00
│ ├─ 000
│ │ └─ 0001 (К)
│ └─ 001 (П)
│ └─ 0010 (свободно)
│ └─ 0011 (свободно)
└─ 01 (Л)
└─ 010 (свободно)
└─ 011 (свободно)
1
├─ 10 (Н)
├─ 11
│ ├─ 110 (О)
│ └─ 111
│ └─ 1110 (Р)
│ └─ 1111 (свободно)
В этом случае, код Л (01) не является префиксом О (110). Код Н (10) не является префиксом Р (1110) и наоборот. Все коды уникальны и не являются префиксами друг друга.
Длина слова ПОРОЛОН:
Возможно ли назначить коды так, чтобы длина была еще меньше?
Для этого нужно, чтобы Н и О получили максимально короткие коды.
Самый короткий код - длина 2. Только 10 доступен.
Если Н = 10, то для О доступны коды длиной 3: 010, 011, 110.
Мы уже выяснили, что 010 и 011 недопустимы из-за префикса Л (01).
Следовательно, для О остается только 110.
Другой вариант: если О = 10 (длина 2).
Тогда для Н, из оставшихся коротких, нам нужно выбрать код, который не будет префиксом Р (1110) и не будет иметь префикс Л (01) или П (001).
Доступные коды длиной 3: 010, 011, 110.
Рассмотрим случай, когда Н = 10.
Слово ПОРОЛОН: П(3), О(?), Р(4), О(?), Л(2), О(?), Н(2).
Чтобы минимизировать длину, О должно получить максимально короткий доступный код.
Коды, которые не могут быть префиксами К, Л, П, Р и не имеют их в качестве префиксов:
Назначаем Н = 10 (длина 2, минимальная возможная).
Теперь ищем кратчайший код для О.
Из доступных: 010, 011, 110.
Проверяем на префиксы:
Значит, единственный допустимый кратчайший код для О при Н=10 это 110 (длина 3).
Суммарная длина слова ПОРОЛОН = 3 (П) + 3 (О) + 4 (Р) + 3 (О) + 2 (Л) + 3 (О) + 2 (Н) = 20.
Возможно ли получить меньшую длину? Для этого нужно, чтобы Н и О получили коды меньшей суммарной длины.
Предположим, мы назначим О = 10 (длина 2).
Тогда Н должно получить какой-то другой код. Кратчайший оставшийся код - 010 (3), 011 (3), 110 (3).
Если О = 10, то:
Если О = 10 и Н = 110:
Длина слова ПОРОЛОН = 3 (П) + 2 (О) + 4 (Р) + 2 (О) + 2 (Л) + 2 (О) + 3 (Н) = 3 + 2 + 4 + 2 + 2 + 2 + 3 = 18.
Эта длина (18) меньше, чем 20.
Таким образом, мы нашли комбинацию, которая дает меньшую длину.
Кодовые слова:
Проверим префиксность:
Все коды уникальны и удовлетворяют условию префиксного кода.
Длина слова ПОРОЛОН: П(001) О(10) Р(1110) О(10) Л(01) О(10) Н(110) = 001 10 1110 10 01 10 110. Длина = 3+2+4+2+2+2+3 = 18.
Это наименьшая возможная длина, так как мы использовали два кода минимальной возможной длины (2) для О и Н.
Если бы существовал другой набор кодов, дающий длину 18, мы бы выбрали тот, у которого наименьшее числовое значение. Код для Н в данном случае — 110.
Если же Н=10, тогда О=110, длина 20.
По условию, если кодов несколько, указать код с наименьшим числовым значением. Нам нужно найти код для буквы Н.
Случай 1: Н = 10, О = 110. Длина 20. Код для Н: 10.
Случай 2: О = 10, Н = 110. Длина 18. Код для Н: 110.
Случай 2 дает меньшую длину слова ПОРОЛОН.
Значит, для буквы Н мы должны назначить код 110.
110