En informática , la subcadena común más larga de dos o más cadenas es la cadena más larga que es subcadena de todas ellas. Puede haber más de una subcadena común más larga. Entre sus aplicaciones se incluyen la deduplicación de datos y la detección de plagio .
A diferencia del problema de la subsecuencia común más larga , que encuentra inserciones o eliminaciones dentro del texto común, el problema de la subcadena común más larga busca una subcadena contigua compartida por ambos textos.
Ejemplos

La imagen muestra dos cadenas de caracteres donde el problema tiene múltiples soluciones. Aunque las ocurrencias de las subcadenas siempre se superponen, es imposible obtener una subcadena común más larga "uniéndolas".
Las cadenas "ABABC", "BABCA" y "ABCBA" tienen solo una subcadena común más larga, a saber, "ABC" de longitud 3. Otras subcadenas comunes son "A", "AB", "B", "BA", "BC" y "C".
ABABC ||| BABCA ||| ABCBA
Definición del problema
Dadas dos cadenas,de longitudyde longitud, encontrar la cadena más larga que sea una subcadena de ambasy.
Una generalización es el problema de la subcadena k - común . Dado el conjunto de cadenas, dóndey. Encuentra para cada, la cadena más larga que aparece como subcadena de al menosinstrumentos de cuerda.
Algoritmos
Se pueden encontrar las longitudes y las posiciones iniciales de las subcadenas comunes más largas deyentiempo con la ayuda de un árbol de sufijos generalizado . Se puede lograr un algoritmo más rápido en el modelo de computación de memoria RAM de palabras si el tamañodel alfabeto de entrada está en. En particular, este algoritmo se ejecuta entiempo usandoespacio. [ 1 ] Resolver el problema mediante programación dinámica cuestaLas soluciones al problema generalizado tomanespacio ytiempo con programación dinámica y tomartiempo con un árbol de sufijos generalizado .
árbol de sufijos

Las subcadenas comunes más largas de un conjunto de cadenas se pueden encontrar construyendo un árbol de sufijos generalizado para las cadenas y luego encontrando los nodos internos más profundos que tienen nodos hoja de todas las cadenas en el subárbol inferior. La figura de la derecha muestra el árbol de sufijos para las cadenas "ABAB", "BABA" y "ABBA", rellenas con terminadores de cadena únicos, para convertirse en "ABAB$0", "BABA$1" y "ABBA$2". Los nodos que representan "A", "B", "AB" y "BA" tienen hojas descendientes de todas las cadenas, numeradas 0, 1 y 2.
Construir el árbol de sufijos llevatiempo (si el tamaño del alfabeto es constante). Si el árbol se recorre de abajo hacia arriba con un vector de bits que indica qué cadenas se ven debajo de cada nodo, el problema de la subcadena común k se puede resolver entiempo. Si el árbol de sufijos está preparado para la recuperación del ancestro común más bajo en tiempo constante , se puede resolver entiempo. [ 2 ]
Programación dinámica
El siguiente pseudocódigo encuentra el conjunto de subcadenas comunes más largas entre dos cadenas mediante programación dinámica :
función SubcadenaComúnMásLarga(S[1..r], T[1..n]) L := arreglo (1..r, 1..n) z := 0 # longitud de la subcadena común más larga encontrada hasta ahora ret := {} para i := 1..r para j := 1..n si S[i] = T[j] si i = 1 o j = 1 L[i, j] := 1 demás L[i, j] := L[i − 1, j − 1] + 1 si L[i, j] > z z := L[i, j] ret := {S[(i − z + 1)..i]} de lo contrario, si L[i, j] = z ret := ret ∪ {S[(i − z + 1)..i]} demás L[i, j] := 0 regresarEste algoritmo se ejecuta entiempo. El array Lalmacena la longitud del sufijo común más largo de los prefijos S[1..i]y T[1..j]que terminan en la posicióni y j, respectivamente. La variable zse utiliza para almacenar la longitud de la subcadena común más larga encontrada hasta el momento. El conjunto retse utiliza para almacenar el conjunto de cadenas que tienen longitud z. El conjunto retse puede guardar de manera eficiente simplemente almacenando el índice i, que es el último carácter de la subcadena común más larga (de tamaño z) en lugar de S[(i-z+1)..i]. Por lo tanto, todas las subcadenas comunes más largas serían, para cada i en ret, S[(ret[i]-z)..(ret[i])].
Los siguientes trucos pueden utilizarse para reducir el uso de memoria de una implementación:
- Conservar únicamente la última y la actual fila de la tabla DP para ahorrar memoria (en lugar de)
- La última fila y la actual se pueden almacenar en la misma matriz unidimensional recorriendo el bucle interno hacia atrás.
- Store only non-zero values in the rows. This can be done using hash-tables instead of arrays. This is useful for large alphabets.
See also
- Longest palindromic substring
- n-gram, all the possible substrings of length n that are contained in a string
References
- ↑Charalampopoulos, Panagiotis; Kociumaka, Tomasz; Pissis, Solon P.; Radoszewski, Jakub (Aug 2021). Mutzel, Petra; Pagh, Rasmus; Herman, Grzegorz (eds.). Faster Algorithms for Longest Common Substring. European Symposium on Algorithms. Leibniz International Proceedings in Informatics (LIPIcs). Vol. 204. Schloss Dagstuhl. doi:10.4230/LIPIcs.ESA.2021.30. Here: Theorem 1, p.30:2.
- ↑Gusfield, Dan (1999) [1997]. Algorithms on Strings, Trees and Sequences: Computer Science and Computational Biology. USA: Cambridge University Press. ISBN 0-521-58519-8.
External links
- Dictionary of Algorithms and Data Structures: longest common substring
- Perl/XS implementation of the dynamic programming algorithm
- Perl/XS implementation of the suffix tree algorithm
- Dynamic programming implementations in various languages on wikibooks
- working AS3 implementation of the dynamic programming algorithm
- Suffix Tree based C implementation of Longest common substring for two strings
- Problems on strings
- Dynamic programming