Задача о наибольшей подпоследовательности-палиндроме — различия между версиями
(→Псевдокод) |
(1) |
||
Строка 1: | Строка 1: | ||
{{В разработке}} | {{В разработке}} | ||
Задача о '''наибольшей подпоследовательности-палиндрома''' — это задача поиска длины наибольшей подпоследовательности-палиндрома, которую можно получить вычеркиванием некоторых букв из данной последовательности. | Задача о '''наибольшей подпоследовательности-палиндрома''' — это задача поиска длины наибольшей подпоследовательности-палиндрома, которую можно получить вычеркиванием некоторых букв из данной последовательности. | ||
− | |||
== Определения == | == Определения == | ||
− | |||
{{Определение|definition='''Палиндромом''' называется строка, которая одинаково читается как слева направо, так и справа налево.}} | {{Определение|definition='''Палиндромом''' называется строка, которая одинаково читается как слева направо, так и справа налево.}} | ||
Строка 9: | Строка 7: | ||
'''''Например''''', '''''HELOLEH''''' является подпоследовательностью-палиндромом строки '''''HTEOLFEOLEH'''''. | '''''Например''''', '''''HELOLEH''''' является подпоследовательностью-палиндромом строки '''''HTEOLFEOLEH'''''. | ||
− | == Решение == | + | == Решение (алгоритм Манакера) == |
− | + | Сначала поймем как находить все подпоследовательности-палиндромы нечётной длины, т.е. вычислять массив <tex>d_1[]</tex>; решение для палиндромов чётной длины (т.е. нахождение массива <tex>d_2[]</tex>) получится небольшой модификацией этого. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | ''''' | + | Для быстрого вычисления будем поддерживать '''границы''' <tex>(l, r)</tex> самого правого из обнаруженных палиндромов (т.е. палиндрома с наибольшим значением <tex>r</tex>). Изначально можно считать <tex>l=0, r=-1</tex>. |
− | + | Итак, пусть вычисляем значение <tex>d_1[i]</tex> для очередного <tex>i</tex>, при этом все предыдущие значения <tex>d_1[]</tex> уже подсчитаны. | |
− | + | * Если <tex>i</tex> не находится в пределах текущего палиндрома, т.е. <tex>i>r</tex>, то просто выполним тривиальный алгоритм. Т.е. будем последовательно увеличивать значение <tex>d_1[i]</tex>, и проверять каждый раз — правда ли текущая подпоследовательность <tex>[i-d_1[i];i+d_1[i]]</tex> является палиндромом. Когда найдем первое расхождение, либо когда дойдем до границ строки <tex>S</tex> — останавливаемся: окончательно посчитали значение <tex>d_1[i]</tex>. После этого мы должны не забыть обновить значения <tex>(l,r)</tex>. | |
− | + | * Рассмотрим случай, когда <tex>i \le r</tex>. Попробуем извлечь часть информации из уже подсчитанных значений <tex>d_1[]</tex>. А именно, отразим позицию <tex>i</tex> внутри палиндрома <tex>(l,r)</tex>, т.е. получим позицию <tex>j=l+(r-i)</tex>, и рассмотрим значение <tex>d_1[j]</tex>. Поскольку <tex>j</tex> — позиция, симметричная позиции <tex>i</tex>, то почти всегда можно просто присвоить <tex>d_1[i]=d_1[j]</tex>. Иллюстрация этого отражения (палиндром вокруг фактически "копируется" в палиндром вокруг <tex>i</tex>):'''IMG1''' | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
== См. также == | == См. также == |
Версия 21:41, 12 декабря 2012
Эта статья находится в разработке!
Задача о наибольшей подпоследовательности-палиндрома — это задача поиска длины наибольшей подпоследовательности-палиндрома, которую можно получить вычеркиванием некоторых букв из данной последовательности.
Определения
Определение: |
Палиндромом называется строка, которая одинаково читается как слева направо, так и справа налево. |
Определение: |
Подпоследовательностью-палиндромом данной строки называется последовательность символов из данной строки, не обязательно идущих подряд, являющаяся палиндромом. |
Например, HELOLEH является подпоследовательностью-палиндромом строки HTEOLFEOLEH.
Решение (алгоритм Манакера)
Сначала поймем как находить все подпоследовательности-палиндромы нечётной длины, т.е. вычислять массив
; решение для палиндромов чётной длины (т.е. нахождение массива ) получится небольшой модификацией этого.Для быстрого вычисления будем поддерживать границы
самого правого из обнаруженных палиндромов (т.е. палиндрома с наибольшим значением ). Изначально можно считать .Итак, пусть вычисляем значение
для очередного , при этом все предыдущие значения уже подсчитаны.- Если не находится в пределах текущего палиндрома, т.е. , то просто выполним тривиальный алгоритм. Т.е. будем последовательно увеличивать значение , и проверять каждый раз — правда ли текущая подпоследовательность является палиндромом. Когда найдем первое расхождение, либо когда дойдем до границ строки — останавливаемся: окончательно посчитали значение . После этого мы должны не забыть обновить значения .
- Рассмотрим случай, когда . Попробуем извлечь часть информации из уже подсчитанных значений . А именно, отразим позицию внутри палиндрома , т.е. получим позицию , и рассмотрим значение . Поскольку — позиция, симметричная позиции , то почти всегда можно просто присвоить . Иллюстрация этого отражения (палиндром вокруг фактически "копируется" в палиндром вокруг ):IMG1
См. также
- Задача о наибольшей общей подпоследовательности
- Задача о наибольшей возрастающей подпоследовательности