Суффиксный массив — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Добавлено новое применение)
(Поиск строки максимальной длины, ветвящейся влево и вправо 1.0)
Строка 22: Строка 22:
 
'''Строка <tex>s</tex> называется ветвящейся вправо в <tex>t</tex>''' (англ. ''right branching string''), если существуют символы <tex>c</tex> и <tex>d</tex>, такие что <tex>c</tex> <tex>\ne</tex> <tex>d</tex> : <tex>sc</tex> и <tex>sd</tex> {{---}} подстроки <tex>t</tex>. Аналогично, '''ветвящаяся влево''' (англ. ''left branching''), если <tex>cs</tex> и <tex>ds</tex> {{---}} подстроки <tex>t</tex>.
 
'''Строка <tex>s</tex> называется ветвящейся вправо в <tex>t</tex>''' (англ. ''right branching string''), если существуют символы <tex>c</tex> и <tex>d</tex>, такие что <tex>c</tex> <tex>\ne</tex> <tex>d</tex> : <tex>sc</tex> и <tex>sd</tex> {{---}} подстроки <tex>t</tex>. Аналогично, '''ветвящаяся влево''' (англ. ''left branching''), если <tex>cs</tex> и <tex>ds</tex> {{---}} подстроки <tex>t</tex>.
 
}}
 
}}
 +
{{Определение
 +
|definition=
 +
'''Левый символ''' для позиции <tex>i</tex> строки <tex>S</tex> {{---}} это символ <tex>S(i-1)</tex>.
 +
}}
 +
 +
Что бы найти максимальную строку, ветвящуюся влево и вправо, строится суффиксный массив из которого исключается суффикс равный самой строке, к примеру для строки <tex>aabcabd</tex> :
 +
{| class="wikitable" border = 1
 +
|-
 +
!Суффиксный массив
 +
|- style = "text-align = right"
 +
| 1 |<tex>abcabd</tex>
 +
|-
 +
| 2 |<tex>abd</tex>
 +
|-
 +
| 3 |<tex>bcabd</tex>
 +
|-
 +
| 4 |<tex>bd</tex>
 +
|-
 +
| 5 |<tex>cabd</tex>
 +
|-
 +
| 6 |<tex>d</tex>
 +
|}
 +
 +
Далее вычисляется <tex>LCP</tex> для суффиксного массива, и находятся левые символы суффиксов:
 +
{| class="wikitable" border = 1
 +
|-
 +
!Левый символ
 +
!Суффиксный массив
 +
!LCP
 +
|- style = "text-align = center"
 +
| 1 |<tex>a</tex>||<tex>abcabd</tex>||<tex>\#</tex>
 +
|-
 +
| 2 |<tex>c</tex>||<tex>abd</tex>||<tex>2</tex>
 +
|-
 +
| 3 |<tex>a</tex>||<tex>bcabd</tex>||<tex>0</tex>
 +
|-
 +
| 4 |<tex>a</tex>||<tex>bd</tex>||<tex>1</tex>
 +
|-
 +
| 5 |<tex>b</tex>||<tex>cabd</tex>||<tex>0</tex>
 +
|-
 +
| 6 |<tex>b</tex>||<tex>d</tex>||<tex>0</tex>
 +
|}
 +
Максимальная строка, ветвящаяся влево и вправо, находится путём проверки значений <tex>LCP</tex> и левого символа:
 +
Ветвление вправо:
 +
*Если <tex>LCP</tex> от пары суффиксов <tex>s_1</tex> и <tex>s_2</tex> больше нуля и не равен длинам этих суффиксов, то строка <tex>s</tex>, равная <tex>s_1[1..LCP(s_1,s_2)]</tex>, ветвится вправо.
 +
Ветвление влево:
 +
*Если левые символы <tex>s_1</tex> и <tex>s_2</tex> не равны, то строка <tex>s</tex>, равная <tex>s_1[1..LCP(s_1,s_2)]</tex>, ветвится влево.
 +
 +
Если выполнены оба условия, то строка ветвится вправо и влево.
 +
С помощью этой проверки находится максимальная строка, ветвящаяся влево и вправо, за <tex>O(n)</tex>.
  
 
==См. также==
 
==См. также==

Версия 22:00, 26 мая 2015

Определение:
Cуффиксным массивом (англ. suffix array) строки [math]s[1 .. n][/math] называется массив [math]suf[/math] целых чисел от [math]1[/math] до [math]n[/math], такой, что суффикс [math]s[suf[i]..n][/math][math]i[/math]-й в лексикографическом порядке среди всех непустых суффиксов строки [math]s[/math].


Пример

[math]s = abacaba[/math]

SuffixArray.png

Значит, суффиксный массив для строки [math]s[/math] равен [math][7, 5, 1, 3, 6, 2, 4][/math].

Применения

  • Позволяет найти все вхождения образца [math]p[/math] в строку [math]s[/math] за время [math]O(|p| + \log(|s|))[/math].
  • Позволяет вычислить наибольший общий префикс (англ. longest common prefix, LCP) для всех соседних в лексикографическом порядке суффиксов строки [math]s[/math] за [math]O(|s|)[/math], то есть построить массив [math]LCP[1 .. |s| - 1][/math], где [math]LCP[i][/math] — длина наибольшего общего префикса суффиксов [math]s[suf[i] .. |s|][/math] и [math]s[suf[i + 1] .. |s|][/math].
  • Позволяет найти количество различных подстрок в строке за время [math]O(|s| \log(|s|))[/math] и [math]O(|s|)[/math] дополнительной памяти.
  • Позволяет найти наименьший циклический сдвиг строки за время [math]O(|s| \log(|s|))[/math].
  • Позволяет найти максимальную по длине строку, ветвящуюся влево и вправо за время [math]SA + O(n)[/math], где [math]SA[/math] — время построения суффиксного массива.

Поиск строки максимальной длины, ветвящейся влево и вправо

Определение:
Строка [math]s[/math] называется ветвящейся вправо в [math]t[/math] (англ. right branching string), если существуют символы [math]c[/math] и [math]d[/math], такие что [math]c[/math] [math]\ne[/math] [math]d[/math] : [math]sc[/math] и [math]sd[/math] — подстроки [math]t[/math]. Аналогично, ветвящаяся влево (англ. left branching), если [math]cs[/math] и [math]ds[/math] — подстроки [math]t[/math].


Определение:
Левый символ для позиции [math]i[/math] строки [math]S[/math] — это символ [math]S(i-1)[/math].


Что бы найти максимальную строку, ветвящуюся влево и вправо, строится суффиксный массив из которого исключается суффикс равный самой строке, к примеру для строки [math]aabcabd[/math] :

Суффиксный массив
[math]abcabd[/math]
[math]abd[/math]
[math]bcabd[/math]
[math]bd[/math]
[math]cabd[/math]
[math]d[/math]

Далее вычисляется [math]LCP[/math] для суффиксного массива, и находятся левые символы суффиксов:

Левый символ Суффиксный массив LCP
[math]a[/math] [math]abcabd[/math] [math]\#[/math]
[math]c[/math] [math]abd[/math] [math]2[/math]
[math]a[/math] [math]bcabd[/math] [math]0[/math]
[math]a[/math] [math]bd[/math] [math]1[/math]
[math]b[/math] [math]cabd[/math] [math]0[/math]
[math]b[/math] [math]d[/math] [math]0[/math]

Максимальная строка, ветвящаяся влево и вправо, находится путём проверки значений [math]LCP[/math] и левого символа: Ветвление вправо:

  • Если [math]LCP[/math] от пары суффиксов [math]s_1[/math] и [math]s_2[/math] больше нуля и не равен длинам этих суффиксов, то строка [math]s[/math], равная [math]s_1[1..LCP(s_1,s_2)][/math], ветвится вправо.

Ветвление влево:

  • Если левые символы [math]s_1[/math] и [math]s_2[/math] не равны, то строка [math]s[/math], равная [math]s_1[1..LCP(s_1,s_2)][/math], ветвится влево.

Если выполнены оба условия, то строка ветвится вправо и влево. С помощью этой проверки находится максимальная строка, ветвящаяся влево и вправо, за [math]O(n)[/math].

См. также

Источники