Encontrar la subcadena palíndromo más larga
La versión actual de la página aún no ha sido revisada por colaboradores experimentados y puede diferir significativamente de la
versión revisada el 16 de julio de 2020; las comprobaciones requieren
2 ediciones .
En Informática , el problema de la subcadena palindrómica más larga es el problema de encontrar la subcadena más larga de una cadena dada que sea un palíndromo .. Por ejemplo, la subcadena palindrómica más larga de "banana" es "anana". La subcadena palindrómica más larga no es necesariamente única; por ejemplo, en la cadena "abracadabra" no hay una subcadena palindrómica de más de tres caracteres, pero hay otras que constan de exactamente tres caracteres, a saber, "aka" y "ada". Algunas aplicaciones desean encontrar todas las subcadenas palindrómicas máximas (es decir, todas las subcadenas que son en sí mismas palíndromos y no se pueden agregar a subcadenas palindrómicas más largas) en lugar de devolver solo una subcadena o devolver la longitud máxima de una subcadena palindrómica.
Manacher (1975 ) inventó un algoritmo lineal en el tiempo para enumerar todos los palíndromos al comienzo de una cadena determinada. Sin embargo, como muestran Apostolico, Breslauer & Galil (1995 ), se puede usar el mismo algoritmo para encontrar todas las subcadenas palindrómicas más largas en cualquier lugar de una cadena dada, nuevamente en tiempo lineal. Por lo tanto, proporciona una solución al problema de encontrar la subcadena palindrómica máxima en tiempo lineal. Jeuring (1994 ) y Gusfield (1997 ) han propuesto soluciones temporales lineales alternativas , quienes describieron una solución basada en el uso de árboles de sufijos . También se conocen algoritmos paralelos eficientes para resolver este problema. [una]
El problema de encontrar la subcadena palindrómica más larga no debe confundirse con el problema de encontrar la subsecuencia palindrómica más larga .
Algoritmo de Manager
Para encontrar el palíndromo más largo en una cadena en tiempo lineal, el algoritmo puede usar las siguientes propiedades de los palíndromos y subpalíndromos:
- El lado izquierdo de un palíndromo es una imagen especular de su lado derecho.
- (Caso 1) Un tercer palíndromo cuyo centro se encuentra en el lado derecho del primer palíndromo tendrá exactamente la misma longitud que el segundo palíndromo cuyo centro está reflejado en el lado izquierdo si el segundo palíndromo se encuentra dentro del primero, alejándose del límite en menos para un personaje.
- (Caso 2) Si el segundo palíndromo tiene un borde común con el primer palíndromo, o se extiende más allá de él, se garantiza que la longitud del tercer palíndromo no será menor que la distancia desde su centro hasta el borde derecho del primer palíndromo. Esta longitud es la distancia desde el centro del segundo palíndromo hasta el carácter más a la izquierda del primer palíndromo.
- Para encontrar la longitud del tercer palíndromo en el caso 2, es necesario comparar los caracteres que siguen al carácter más a la derecha del primer palíndromo con su imagen especular sobre el centro del tercer palíndromo hasta que se agote la cadena o se produzca una desigualdad de se encuentran los caracteres.
- (Caso 3) Ni el primer ni el segundo palíndromo proporcionan información para determinar la longitud de un cuarto palíndromo cuyo centro se encuentra fuera del límite del primer palíndromo.
- Por lo tanto, para determinar de izquierda a derecha las longitudes palindrómicas de las subcadenas en una cadena, es deseable tener un palíndromo de referencia (que actúe como el primer palíndromo) cuyos caracteres ocupen las posiciones más a la derecha en la cadena (y por lo tanto el tercer palíndromo en el caso 2 y el cuarto palíndromo en el caso 3 puede sustituir al primer palíndromo, para convertirse en el nuevo palíndromo de referencia).
- Con respecto a la estimación del tiempo para determinar la longitud palindrómica para cada carácter de la cadena: en el Caso 1 no se realiza ninguna comparación de caracteres, en los Casos 2 y 3 solo los caracteres de la cadena que se encuentran más allá del carácter más a la derecha del palíndromo de referencia son candidatos para comparación (y, por lo tanto, el Caso 3 siempre conduce a un cambio en el palíndromo de referencia cuando el Caso 2 cambia el palíndromo de referencia solo si resulta que la longitud del tercer palíndromo es en realidad mayor que su longitud mínima prometida).
- Para palíndromos de grado par, el centro se encuentra entre los dos símbolos centrales del palíndromo.
Implementación
Dejar:
- s es una cadena de N caracteres
- s2 es una cadena derivada de s, que consta de N * 2 + 1 elementos, cada elemento corresponde a uno de: N caracteres en s, N-1 espacios entre caracteres y límites, y espacios antes del primero y después del último carácter de la cadena s respectivamente
- Los límites en s2 no son diferentes en términos de encontrar la longitud de un palíndromo
- Sea p una matriz de radios de palíndromo, es decir, la distancia desde el centro a cualquiera de los caracteres más lejanos del palíndromo (es decir, un palíndromo de longitud 3 tiene un radio palindrómico de 1)
- Sea c la posición del centro del palíndromo que contiene el carácter más cercano al extremo derecho de s2 (la longitud de este palíndromo es p[c]*2+1)
- Sea r la posición del límite más a la derecha de este palíndromo (es decir, r = c + p[c])
- Sea i la posición del elemento (es decir, espacio o carácter) en s2 cuyo radio palindrómico se determina, con i siempre ubicado a la derecha de c
- Sea i_mir la imagen especular de i con respecto a c (es decir, {i, i_mir} = {6, 4}, {7, 3}, {8, 2},... cuando c = 5 (por lo tanto, i_mir = c * 2 - i))
Resultado: el palíndromo más largo o el primer carácter de la cadena
#incluir <cadena>
#incluir <vector>
utilizando el espacio de nombres estándar ;
cadena palíndromo más largo ( const cadena & s ){
vector < char > s2 ( s . tamaño () * 2 + 1 , '#' );
//crear una pseudocadena con límites '#'
para ( int i = 0 ; i != s . size (); ++ i ){
s2 [ yo * 2 + 1 ] = s [ yo ];
}
intp [ s2._ _ _ tamaño ()];
int r , c , índice , i_mir ;
int maxLen = 1 ;
i_mir = índice = r = c = 0 ;
para ( int i = 1 ; i != s2 . tamaño () - 1 ; ++ i ){
i_mir = 2 * c - i ;
//Si caemos dentro del radio del resultado anterior,
//entonces el valor inicial del radio actual se puede tomar del resultado del espejo p [ i ] = r > i ? min ( p [ i_mir ], r - i ) : 0 ;
while ( i > p [ i ] && ( i + p [ i ] + 1 ) < s2 . size () && s2 [ i - p [ i ] - 1 ] == s2 [ i + p [ i ] + 1 ] )
++ pag [ yo ];
si ( pags [ yo ] + yo > r ){
c = yo ;
r = yo + pag [ yo ];
}
si ( maxLen < p [ i ]){
maxLen = p [ i ];
índice = yo ;
}
}
//Asignar las posiciones encontradas a la cadena original
return s . substr (( índice - maxLen ) / 2 , maxLen );
}
Notas
- ↑ Crochemore & Rytter (1991 ), Apostolico, Breslauer & Galil (1995 ).
Literatura
- Apostólico, Alberto; Breslauer, Dany & Galil, Zvi (1995), Detección paralela de todos los palíndromos en una cadena , Theoretical Computer Science Vol. 141 (1–2): 163–173 , DOI 10.1016/0304-3975(94)00083-U .
- Crochemore, Maxime & Rytter, Wojciech (1991), Utilidad del algoritmo Karp-Miller-Rosenberg en cálculos paralelos en cadenas y matrices , Theoretical Computer Science Vol. 88 (1): 59–82 , DOI 10.1016/0304-3975(91 )90073-B .
- Crochemore, Maxime & Rytter, Wojciech (2003), 8.1 Búsqueda de palabras simétricas, Jewels of Stringology: Text Algorithms , World Scientific, p. 111–114, ISBN 978-981-02-4897-0 .
- Gusfield, Dan (1997), 9.2 Finding all maximal palindromes in linear time , Algorithms on Strings, Trees, and Sequences , Cambridge: Cambridge University Press, p. 197–199, ISBN 0-521-58519-8 , DOI 10.1017/CBO9780511574931 .
- Jeuring, Johan (1994), La derivación de algoritmos en línea, con una aplicación para encontrar palíndromos , Algorithmica Vol . 11 (2): 146–184 , DOI 10.1007/BF01182773 .
- Manacher, Glenn (1975), Un nuevo algoritmo "en línea" de tiempo lineal para encontrar el palíndromo inicial más pequeño de una cadena , Journal of the ACM volumen 22 (3): 346–351 , DOI 10.1145/321892.321896 .
Enlaces
Este artículo incorpora texto de la
subcadena palindrómica más larga en PEGWiki bajo una licencia Creative Commons Attribution (
CC-BY-3.0 ).