Supongamos que se nos da una colección de cadenas, . Me gustaría saber si alguna de esas cadenas es una subcadena de cualquier otra cadena de la colección. En otras palabras, me gustaría un algoritmo para la siguiente tarea:S 1 , ... , S n
Entrada:
Salida: tal que es una subcadena de y , o Ninguno si hay tal existenS i S j i ≠ j i , j
¿Existe un algoritmo eficiente para esto?
Si reemplazamos "subcadena" por "prefijo", hay un algoritmo eficiente (clasifique las cadenas, luego realice un escaneo lineal para comparar cadenas adyacentes; la clasificación asegurará que las subcadenas sean adyacentes). Pero parece más difícil probar si alguna cadena es una subcadena de cualquier otra cadena. Un algoritmo ingenuo es iterar sobre todos los pares , pero esto requiere pruebas de subcadena . ¿Hay un algoritmo más eficiente?Θ ( n 2 )
Supongo que podríamos llamar a esto "prueba de subcadena de todos los pares", o algo así.
Mi objetivo final es podar la colección para que ninguna cadena sea una subcadena de ninguna otra, eliminando cada una que sea una subcadena de otra cosa en la colección.
Respuestas:
Puede construir un árbol de sufijos en tiempo lineal y verificar si hay un nodo interno que corresponde a una cadena completa (tiempo constante por nodo).
Con más detalle, suponga que se nos dan las cadenas .s1, ... , snorte∈ Σ∗
Construya un árbol de sufijos (generalizado) de con n marcadores terminales distintos por pares .s1PS1, s2PS2, ... , snortePSnorte norte PS1, ... , $norte∉ Σ
Usando el algoritmo de Ukkonen , esto se puede hacer en tiempo lineal; lineal en la suma de todas las longitudes de cadena.
Suponiendo que etiqueta las hojas con si representan el sufijo de s i , recorra el árbol y encuentre esas n hojas etiquetadas ( i , 0( i , j ) syo[ j . . El | syoEl | ] syo norte , es decir, las hojas que corresponden al total instrumentos de cuerda.( i , 0 )
Esto lleva un tiempo lineal en el tamaño del árbol, que es lineal en el tamaño de entrada.
Las hojas descendientes del padre de (que se alcanza mediante un borde etiquetado como ) representan todas las coincidencias del conjunto; Esto se desprende de la invariante básica de los árboles de sufijos. Encuentre cualquier coincidencia descendiendo a cualquier hoja (pero ).( i , 0 ) ( i , 0 )PSyo ( i , 0 )
Esto nuevamente toma tiempo lineal.
Los distintos marcadores terminales no son realmente necesarios; una sola utilizada para terminar todas las cadenas es suficiente siempre que permita múltiples etiquetas por hoja.
fuente