Наибольшая общая подстрока: различия между версиями
Перейти к навигации
Перейти к поиску
[непроверенная версия] | [отпатрулированная версия] |
Содержимое удалено Содержимое добавлено
FANATID (обсуждение | вклад) →Реализация на C++: - улучшен код |
FANATID (обсуждение | вклад) подправил меню |
||
Строка 39: | Строка 39: | ||
Очевидно, трудоемкость такого алгоритма составляет ''[[«O» большое и «o» малое|O]](mn)''. |
Очевидно, трудоемкость такого алгоритма составляет ''[[«O» большое и «o» малое|O]](mn)''. |
||
=== Реализация на C++ === |
==== Реализация на C++ ==== |
||
<source lang="cpp"> |
<source lang="cpp"> |
||
string |
string |
||
Строка 45: | Строка 45: | ||
{ |
{ |
||
string ret; |
string ret; |
||
int maxlen = 0, mi |
int maxlen = 0, mi; |
||
int **dt; |
int **dt; |
||
Строка 64: | Строка 64: | ||
maxlen = dt[i][j]; |
maxlen = dt[i][j]; |
||
mi = i; |
mi = i; |
||
mj = j; |
|||
} |
} |
||
} |
} |
||
Строка 78: | Строка 77: | ||
</source> |
</source> |
||
=== Реализация на C# === |
==== Реализация на C# ==== |
||
<!-- // в английской версии статьи |
<!-- // в английской версии статьи |
||
//http://en.wikibooks.org/wiki/Algorithm_implementation/Strings/Longest_common_substring |
//http://en.wikibooks.org/wiki/Algorithm_implementation/Strings/Longest_common_substring |
||
Строка 116: | Строка 115: | ||
</source> |
</source> |
||
=== Реализация на Haskell === |
==== Реализация на Haskell ==== |
||
<source lang="Haskell"> |
<source lang="Haskell"> |
||
import Data.List |
import Data.List |
Версия от 06:46, 7 января 2011
Наибольшая общая подстрока (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).
Реализация на C++
string
LCS(const string& s1, const string& s2)
{
string ret;
int maxlen = 0, mi;
int **dt;
dt = new int*[s1.length() + 1];
dt[0] = new int[s2.length() + 1];
memset(dt[0], 0, (s2.length() + 1)*sizeof(int));
for (int i = 1; i <= (int) s1.length(); ++i)
{
dt[i] = new int[s2.length() + 1];
memset(dt[i], 0, (s2.length() + 1)*sizeof(int));
for (int j = 1; j <= (int) s2.length(); ++j)
{
if (s1[i-1] == s2[j-1])
{
dt[i][j] = dt[i-1][j-1] + 1;
if (maxlen < dt[i][j])
{
maxlen = dt[i][j];
mi = i;
}
}
}
delete dt[i-1];
}
delete dt[s1.length()];
delete dt;
for (; maxlen > 0; --maxlen)
ret = s1[--mi] + ret;
return ret;
}
Реализация на C#
public static int LongestCommonSubstring( string str1, string str2 )
{
if( String.IsNullOrEmpty( str1 ) || String.IsNullOrEmpty( str2 ) )
return 0;
List<int[]> num = new List<int[]>();
int maxlen = 0;
for( int i = 0; i < str1.Length; i++ )
{
num.Add( new int[ str2.Length ] );
for( int j = 0; j < str2.Length; j++ )
{
if( str1[ i ] != str2[ j ] )
num[ i ][ j ] = 0;
else
{
if( ( i == 0 ) || ( j == 0 ) )
num[ i ][ j ] = 1;
else
num[ i ][ j ] = 1 + num[ i - 1 ][ j - 1 ];
if( num[ i ][ j ] > maxlen )
maxlen = num[ i ][ j ];
}
if( i >= 2 )
num[ i - 2 ] = null;
}
}
return maxlen;
}
Реализация на Haskell
import Data.List
import Data.Function
lcstr xs ys = maximumBy (compare `on` length) . concat $ [f xs' ys | xs' <- tails xs] ++ [f xs ys' | ys' <- drop 1 $ tails ys]
where f xs ys = scanl g [] $ zip xs ys
g z (x, y) = if x == y then z ++ [x] else []
Алгоритм, использующий суффиксное дерево
См. также
Это заготовка статьи по математике. Помогите Википедии, дополнив её. |