Наибольшая общая подстрока: различия между версиями

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
[отпатрулированная версия][отпатрулированная версия]
Содержимое удалено Содержимое добавлено
м Checkwiki #1. Исправление избыточного префикса "Шаблон:"
 
(не показаны 44 промежуточные версии 37 участников)
Строка 1: Строка 1:
[[Наибольшая общая подстрока|Наибольшая общая подстрока (longest common substring)]] — подстрока двух или более строк, имеющая максимальную длину.
'''Наибольшая общая подстрока''' ({{lang-en|longest common substring}}) — подстрока двух или более строк, имеющая максимальную длину.


Формально, наибольшей общей [[Подстрока|подстрокой]] строк <math>s_1,s_2,\ldots s_n</math> называется строка <math>\left.w^*\right.</math>, которая удовлетворяет условию <math>\|w^*\| = \max(\{\|w\||w\sqsubseteq s_i, i=1,\ldots n\})</math>, операция <math>w\sqsubseteq s_i</math> обозначает что строка <math>\left.w\right.</math> является (возможно несобственной) подстрокой строки <math>\left.s_i\right.</math>.
Формально, наибольшей общей [[Подстрока|подстрокой]] строк <math>s_1,s_2,\ldots s_n</math> называется строка <math>\left.w^*\right.</math>, которая удовлетворяет условию <math>\|w^*\| = \max(\{\|w\||w\sqsubseteq s_i, i=1,\ldots n\})</math>, операция <math>w\sqsubseteq s_i</math> обозначает что строка <math>\left.w\right.</math> является (возможно несобственной) подстрокой строки <math>\left.s_i\right.</math>.


Решение задачи поиска наибольшей общей подстроки для двух строк <math>\left.s_1\right.</math> и <math>\left.s_2\right.</math>, длины которых <math>\left.m\right.</math> и <math>\left.n\right.</math> соответственно, заключается в заполнении таблицы <math>\left.A_{ij}\right.</math> размером <math>(m+1)\times (n+1)</math> по следующему правилу, принимая, что символы в строке нумеруются от единицы.
==Алгоритмы поиска наибольшей общей подстроки==
===Наивный алгоритм===
Решение задачи поиска наибольшей общей подстроки для двух строк <math>\left.s_1\right.</math> и <math>\left.s_2\right.</math>, длины которых <math>\left.m\right.</math> и <math>\left.n\right.</math> соответственно, заключается в заполнении таблицы <math>\left.A_{ij}\right.</math> размером <math>(m+1)\times (n+1)</math> по следующему правилу, принимая, что символы в строке нумеруются от единицы.


<math>\left\{
<math>\left\{
Строка 19: Строка 17:
Максимальное число <math>\left. A_{uv} \right. </math> в таблице это и есть длина наибольшей общей подстроки, сама подстрока:
Максимальное число <math>\left. A_{uv} \right. </math> в таблице это и есть длина наибольшей общей подстроки, сама подстрока:


<math>s_1[u-A_{uv}+1]\ldots s_1[u]</math> и <math>s_2[v-A_{uv}+1]\ldots s_2[vu]</math>.
<math>s_1[u-A_{uv}+1]\ldots s_1[u]</math> и <math>s_2[v-A_{uv}+1]\ldots s_2[v]</math>.


В таблице заполнены значения для строк '''SUBSEQUENCE''' и '''SUBEUENCS''':
В таблице заполнены значения для строк '''SUBSEQUENCE''' и '''SUBEUENCS''':


'''SUBSEQUENCE'''
'''SUBSEQUENCE'''
Строка 32: Строка 30:
'''E''' 00000'''1'''00'''2'''00'''1'''
'''E''' 00000'''1'''00'''2'''00'''1'''
'''N''' 000000000'''3'''00
'''N''' 000000000'''3'''00
'''C''' 0000000000'''4'''0
'''C''' 0000000000<font color="red">'''4'''</font>0
'''S''' 0'''1'''00'''1'''0000000
'''S''' 0'''1'''00'''1'''0000000
Получаем наибольшую общую подстроку '''UENC'''
Получаем наибольшую общую подстроку '''UENC.'''


Очевидно, трудоемкость такого алгоритма составляет ''[[«O» большое и «o» малое|O]](mn)''.
Сложность такого алгоритма составляет ''[[«O» большое и «o» малое|O]](mn)''.


=== Реализация на Haskell ===
<source lang="Haskell">
import Data.List
import Data.Function

lcstr xs ys = maximumBy (compare `on` length) . concat $ [find xs' ys | xs' <- tails xs] ++ [find xs ys' | ys' <- drop 1 $ tails ys]
where find xs ys = scanl grow [] $ zip xs ys
grow z (x, y) = if x == y then z ++ [x] else []
</source>

===Алгоритм, использующий [[суффиксное дерево]]===
== См. также ==
== См. также ==
* [[Суффиксное дерево]]
* [[Суффиксное дерево]]
Строка 55: Строка 42:
* [[Наибольшая общая подпоследовательность]]
* [[Наибольшая общая подпоследовательность]]


== Примечания ==
{{math-stub}}
{{примечания}}{{Строки}}{{нет ссылок|дата=7 июня 2019}}


[[Категория:Строковые алгоритмы]]
[[Категория:Строковые алгоритмы]]

[[en:Longest common substring problem]]

Текущая версия от 07:23, 11 марта 2020

Наибольшая общая подстрока (англ. longest common substring) — подстрока двух или более строк, имеющая максимальную длину.

Формально, наибольшей общей подстрокой строк называется строка , которая удовлетворяет условию , операция обозначает что строка является (возможно несобственной) подстрокой строки .

Решение задачи поиска наибольшей общей подстроки для двух строк и , длины которых и соответственно, заключается в заполнении таблицы размером по следующему правилу, принимая, что символы в строке нумеруются от единицы.

Максимальное число в таблице это и есть длина наибольшей общей подстроки, сама подстрока:

и .

В таблице заполнены значения для строк SUBSEQUENCE и SUBEUENCS:

   SUBSEQUENCE
  000000000000
S 010010000000
U 002000010000
B 000300000000
E 000001001001
U 001000010000
E 000001002001
N 000000000300
C 000000000040
S 010010000000

Получаем наибольшую общую подстроку UENC.

Сложность такого алгоритма составляет O(mn).

Примечания

[править | править код]