Изменения
→Применение
== Описание алгоритма ==
Изначально каждое возможное значение байта записывается в список (алфавит), в ячейку с номером, равным значению байта, т.е. <tex>(0, 1, 2, 3, …\dots, 255)</tex>. В процессе обработки данных этот список изменяется. По мере поступления очередного символа на выход подается номер элемента, содержащего его значение. После чего этот символ перемещается в начало списка, смещая остальные элементы вправо.
Современные алгоритмы (например, bzip2<ref>[http://ru.wikipedia.org/wiki/Bzip2 {{---}} bzip2]</ref>) перед алгоритмом MTF используют [[преобразование Барроуза-Уиллера|алгоритм BWT]], поэтому в качестве примера рассмотрим строку <tex>\mathtt{S} = BCABAAA</tex>''"BCABAAA"'', полученную из строки ''"ABACABA"'' в результате [[Преобразование Барроуза-Уиллера|преобразования Барроуза-Уиллера]]. Первый символ строки <tex>\mathtt{S}</tex> 'B' является вторым элементом алфавита ''"ABC"'', поэтому на вывод подаётся <tex>1</tex>. После перемещения 'B' в начало алфавита тот принимает вид ''"BAC"''. Дальнейшая работа алгоритма показана в таблице:
{| class="wikitable"
|}
Таким образом, результат работы алгоритма: <tex>MTF(\mathtt{S}) = 1222100</tex> ''"1222100"''.
Вот примерная реализация этого алгоритма. Здесь массив <tex>\mathtt{alphabet}</tex> хранит количество символов перед символом <tex>\mathtt{S}[\mathtt{i}]</tex>, <tex>\mathtt{N}</tex> {{---}} длина строки <tex>\mathtt{S}</tex>.
'''list<int>''' mtf(N):
'''list<int>''' result(N)
помещаем символ S[i] в начало алфавита
'''return''' result
Данный алгоритм работает за <tex>O(\mathtt{N} \cdot \mathtt{M})</tex>, где <tex>\mathtt{N}M</tex> {{---}} размер алфавита, <tex>\mathtt{M}N</tex> {{---}} длина строки, что не очень быстро. Этот алгоритм можно реализовать за <tex>O(\mathtt{N}\log(\mathtt{N+M}))</tex>.
== Описание алгоритма за O(N log(N+M)) ==
'''list<int>''' mtf(N):
'''list<int>''' result(N)
'''return''' result
Функции <codetex> '''int''' sum(left, right) result = 0 '''for''' i = left '''to''' right result = result + used[i] '''return''' result\mathtt{split}</tex> и <tex>\mathtt{merge}</codetex>{{---}} стандартные функции для [[Декартово_дерево|декартова дерева]].
== Обратное преобразование ==
Пусть даны строка <tex>\mathtt{S} = 1222100</tex>''"1222100"'' и исходный алфавит ''"ABC"''. Символ с номером <tex>1</tex> в алфавите {{---}} это 'B'. На вывод подаётся 'B', и этот символ перемещается в начало алфавита. Символ с номером <tex>2</tex> в алфавите {{---}} это 'AC', поэтому 'AC' подается на вывод и перемещается в начало алфавита. Дальнейшее преобразование происходит аналогично.
{| class ="wikitable"
|}
Значит, исходная строка <tex>MTF^{-1}(\mathtt{S}) = BCABAAA</tex>''"BCABAAA"''.
== Применение ==
| 0 || 16 || 4/5 || 0
|-
| 1 || 2 1 || 1/10 20 || 10110
|-
| 2 || 1 || 1/20 || 110111
|-
| 3 || 1 2 || 1/20 10 || 11110
|}
В результате сжатия получаем последовательность длиной <tex>16\cdot1 + 2\cdot2 + 3\cdot2 = 26</tex> бит. Стоит заметить, что выигрыш от применения [[Арифметическое кодирование|арифметического кодирования]] для данного примера будет еще значительней.
== См. также ==
* [[Преобразование Барроуза-Уиллера]]
* [[Алгоритм LZW]]
== Примечания ==
<references />
== Источники информации ==
# Ryabko, B. Ya. ''Data compression by means of a «book stack»'', Problems of Information Transmission, 1980, v. 16: (4), pp. 265–269.
# Ryabko, B. Ya.; Horspool, R. Nigel; Cormack, Gordon V. Comments to: ''«A locally adaptive data compression scheme»'' by J. L. Bentley, D. D. Sleator, R. E. Tarjan and V. K. Wei. Comm. ACM 30 (1987), no. 9, 792—794.