Алгоритм Крочемора — различия между версиями
Строка 1: | Строка 1: | ||
{{Определение | {{Определение | ||
|definition = | |definition = | ||
− | '''Тандемным повтором''' (tandem repeat) в строке называются два вхождения какой-либо подстроки подряд. Иными словами, тандемный повтор описывается парой индексов <tex>i < j</tex> такими, что подстрока <tex>s[i \ldots j]</tex> | + | '''Тандемным повтором''' (англ. "tandem repeat") в строке называются два вхождения какой-либо подстроки подряд. Иными словами, тандемный повтор описывается парой индексов <tex>i < j</tex> такими, что подстрока <tex>s[i \ldots j]</tex> {{---}} это две одинаковые строки, записанные подряд. |
}} | }} | ||
− | '''Алгоритм Крочемора''' (англ. Crochemore algorithm) - алгоритм на строках, позволяющий найти все тандемные повторы в строке <tex>s[1..n]</tex> за <tex>O(n \log n)</tex> | + | '''Алгоритм Крочемора''' (англ. Crochemore algorithm) {{---}} алгоритм на строках, позволяющий найти все тандемные повторы в строке <tex>s[1..n]</tex> за <tex>O(n \log n)</tex> |
= Алгоритм = | = Алгоритм = | ||
Строка 34: | Строка 34: | ||
Если нам заранее известен алфавит и он индексирован, то мы можем выполнить данное вычисление за <tex>O(n)</tex>. | Если нам заранее известен алфавит и он индексирован, то мы можем выполнить данное вычисление за <tex>O(n)</tex>. | ||
− | Далее для <tex>l = 2</tex> мы хотим найти все повторяющиеся подстроки длины <tex>2</tex>. Поскольку повторяющиеся подстроки длины <tex>l \ | + | Далее для <tex>l = 2</tex> мы хотим найти все повторяющиеся подстроки длины <tex>2</tex>. Поскольку повторяющиеся подстроки длины <tex>l \geqslant 2</tex> будут иметь общий префикс длиной <tex>l - 1</tex>, то вычисления уровня <tex>l</tex> должны привести к последовательностям, которые будут подпоследовательностями последовательностей, вычисленных на уровне <tex>l - 1</tex>. Другими словами, разбиение на уровне <tex>l \geqslant 2</tex> {{---}} декомпозиция разбиения на уровне <tex>l - 1</tex>: |
{|class="wikitable" style="text-align:center" | {|class="wikitable" style="text-align:center" | ||
Строка 69: | Строка 69: | ||
Декомпозицию каждой последовательности можно получить косвенным путем, а не путем прямых вычислений. Идея такого подхода состоит в следующем: | Декомпозицию каждой последовательности можно получить косвенным путем, а не путем прямых вычислений. Идея такого подхода состоит в следующем: | ||
− | на каждом уровне <tex>l</tex> выполняется непосредственная декомпозиция каждой последовательности <tex>c^{ | + | на каждом уровне <tex>l</tex> выполняется непосредственная декомпозиция каждой последовательности <tex>c^{l}_j</tex>. Более точно, если <tex>c^{l}_j = \langle p_1, p_2, \ldots , p_r \rangle</tex>, то необходимо проверить совпадение букв <tex>s[p_1 + l], s[p_2 + l], \ldots, s[p_r + l]</tex>, и, если какие-либо пары букв <tex>s[p_i + l]</tex> и <tex>s[p_j + l]</tex> равны, то <tex>p_i</tex> и <tex>p_j</tex> помещаются в одну и ту же последовательность на уровне <tex>l + 1</tex>. |
Строка 75: | Строка 75: | ||
− | Для каждой позиции <tex>p_i > 1</tex> известно, что подстрока <tex>s[p_i - 1 \ldots p_i + l - 1]</tex> (длиной <tex>l + 1</tex>) относится к некоторой последовательности <tex>c^{ | + | Для каждой позиции <tex>p_i > 1</tex> известно, что подстрока <tex>s[p_i - 1 \ldots p_i + l - 1]</tex> (длиной <tex>l + 1</tex>) относится к некоторой последовательности <tex>c^{l + 1}_{j'}</tex> на уровне <tex>l + 1</tex>. Поскольку последовательность <tex>c^{l}_{j}</tex> соответствует уникальной подстроке строки <tex>s</tex>, то каждая такая последовательность <tex>c^{l + 1}_{j'}</tex> должна формироваться из тех же позиций <tex>p_{i_1}, p_{i_2}, \ldots , p_{i_k}</tex> последовательности <tex>c^{l}_{j}</tex>, которые определяют класс эквивалентности |
<tex>s[p_{i_1} - 1] = s[p_{i_2} - 1] = \ldots = s[p_{i_k} - 1]</tex>. | <tex>s[p_{i_1} - 1] = s[p_{i_2} - 1] = \ldots = s[p_{i_k} - 1]</tex>. | ||
Строка 88: | Строка 88: | ||
= Источники = | = Источники = | ||
− | * ''Билл Смит'' '''Методы и алгоритмы вычислений на строках'''. Пер. с англ. | + | * ''Билл Смит'' '''Методы и алгоритмы вычислений на строках'''. Пер. с англ.{{---}} М.:Издательский дом "Вильямс", 2006. ISBN 5-8459-1081-1 |
− | * [http://e-maxx.ru/algo/string_tandems E-maxx | + | * [http://e-maxx.ru/algo/string_tandems E-maxx {{---}} Поиск всех тандемных повторов в строке. Алгоритм Мейна-Лоренца] |
[[Категория: Поиск тандемных повторов]] | [[Категория: Поиск тандемных повторов]] | ||
[[Категория: Алгоритмы и структуры данных]] | [[Категория: Алгоритмы и структуры данных]] | ||
[[Категория: Дискретная математика и алгоритмы]] | [[Категория: Дискретная математика и алгоритмы]] |
Версия 18:45, 11 июня 2014
Определение: |
Тандемным повтором (англ. "tandem repeat") в строке называются два вхождения какой-либо подстроки подряд. Иными словами, тандемный повтор описывается парой индексов | такими, что подстрока — это две одинаковые строки, записанные подряд.
Алгоритм Крочемора (англ. Crochemore algorithm) — алгоритм на строках, позволяющий найти все тандемные повторы в строке за
Алгоритм
Разобьем описание алгоритма на две части: сначала покажем упрощенный алгоритм, работающий за
, а затем попытаемся его оптимизировать доУпрощенный алгоритм
Рассмотрим следующую строку Фиббоначи:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | |
a | b | a | a | b | a | b | a | a | b | a | a | b |
Будем вычислять все повторяющиеся подстроки длины , где . Зная эти данные, мы автоматически находим все тандемные повторы.
Предположим, что в строке
вычислены последовательности позиций, в которых встречаются одинаковые символы:<1, 3, 4, 6, 8, 9, 11, 12> | <2, 5, 7, 10, 13> | |
a | b |
Если нам заранее известен алфавит и он индексирован, то мы можем выполнить данное вычисление за
.Далее для
мы хотим найти все повторяющиеся подстроки длины . Поскольку повторяющиеся подстроки длины будут иметь общий префикс длиной , то вычисления уровня должны привести к последовательностям, которые будут подпоследовательностями последовательностей, вычисленных на уровне . Другими словами, разбиение на уровне — декомпозиция разбиения на уровне :Последовательная декомпозиция строки | |||||
---|---|---|---|---|---|
<1, 4, 6, 9, 12> | <3, 8, 11> | <2, 5, 7, 10> | <13> | ||
ab | aa | ba | b$ | ||
<1, 4, 6, 9> | <12> | <3, 8, 11> | <2, 7, 10> | <5> | |
aba | aa$ | aab | baa | bab | |
<1, 6, 9> | <4> | <3, 8> | <11> | <2, 7, 10> | |
abaa | abab | aaba | aab$ | baab | |
<1, 6, 9> | <3> | <8> | <2, 7> | <10> | |
abaab | aabab | aabaa | baaba | baab$ | |
<1, 6> | <9> | <2> | <7> | ||
abaaba | abaab$ | baabab | baabaa | ||
<1> | <6> | ||||
abaabab | abaabaa |
Если реализовывать процесс декомпозиции "наивно", то поучаем сложность
Оптимизация
Декомпозицию каждой последовательности можно получить косвенным путем, а не путем прямых вычислений. Идея такого подхода состоит в следующем: на каждом уровне
выполняется непосредственная декомпозиция каждой последовательности . Более точно, если , то необходимо проверить совпадение букв , и, если какие-либо пары букв и равны, то и помещаются в одну и ту же последовательность на уровне .
Заметим, что декомпозицию можно выполнить, основываясь не на разбиваемой последовательности, а на последовательностях, относительно которых будут разбиваться другие последовательности.
Для каждой позиции известно, что подстрока (длиной ) относится к некоторой последовательности на уровне . Поскольку последовательность соответствует уникальной подстроке строки , то каждая такая последовательность должна формироваться из тех же позиций последовательности , которые определяют класс эквивалентности
.
Таким образом, декомпозицию на уровне можно выполнить косвенным путем, рассматривая каждую последовательность уровня с позиции, находящейся на левее от начальной позиции этой последовательности.
...
Псевдокод
Реализация
Источники
- Билл Смит Методы и алгоритмы вычислений на строках. Пер. с англ.— М.:Издательский дом "Вильямс", 2006. ISBN 5-8459-1081-1
- E-maxx — Поиск всех тандемных повторов в строке. Алгоритм Мейна-Лоренца