¿Qué es una explicación intuitiva sobre cómo funcionan las matrices de sufijos?

Los sufijos de una cadena contienen (casi) toda la información sobre todas las posibles subcadenas de una cadena. Por ejemplo, suponga que está pensando en la subcadena “racada” de la cadena “ab racada bra”. Oh, mira, existe el sufijo “sujetador racada ” que comienza con tu subcadena. Eso es casi lo mismo.

¿Porque es esto importante? Porque hay subcadenas [math] \ Theta (n ^ 2) [/ math] en una cadena de letras [math] n [/ math], pero solo sufijos no vacíos [math] n [/ math]. Por ejemplo, sería bastante costoso ordenar todas las subcadenas posibles: para producir su orden ordenado, sin duda necesitaría [math] \ Omega (n ^ 2) [/ math] pasos porque debe, al menos, generar cada uno de ellos . Por otro lado, en teoría podría ser posible ordenar solo los sufijos más rápido que eso.

Y una vez que la gente se dio cuenta de que en realidad es posible y se le ocurrieron algoritmos eficientes e inteligentes para hacerlo, nació la matriz de sufijos.

La matriz de sufijos es simplemente una representación compacta de la lista ordenada de todos los sufijos. Por ejemplo, considere la cadena “banana”. Hay seis sufijos no vacíos: “banana”, “anana”, “nana”, “ana”, “na” y “a”. Podemos llamarlos 0, 1, 2, 3, 4 y 5, en este orden. (El número de un sufijo es el índice del carácter donde comienza en la cadena original). Si clasificamos (*) estos sufijos, obtenemos el siguiente orden: “a”, “ana”, “anana”, “banana “,” na “y” nana “. En otras palabras, (5,3,1,0,4,2). Esta es la matriz de sufijos para la cadena “banana”.

(*) Tenga en cuenta que los algoritmos eficientes en realidad no construyen todos los sufijos y luego los ordenan usando un algoritmo general, eso sería demasiado lento. En cambio, usan trucos inteligentes basados ​​en el hecho de que sabemos que las cadenas que estamos ordenando son sufijos de la misma cadena. El truco básico aquí: cualquier sufijo de un sufijo es simplemente otro sufijo de la cadena original. Por ejemplo, si sabe que los sufijos 23 y 47 comparten las mismas 4 primeras letras, puede compararlos comparando los sufijos 23 + 4 y 47 + 4.

Una vez que tengamos la matriz de sufijos, podemos usarla para responder muchos tipos de consultas sobre la cadena original. Para un ejemplo simple, considere el problema de búsqueda de subcadenas estándar: aquí hay una nueva cadena de caracteres cortos (“la aguja”), ¿aparece en alguna parte de la cadena original de caracteres largos (“el pajar”)?

Sin la matriz de sufijos (o una estructura de datos precalculada similar), lo mejor que puede hacer es un algoritmo de búsqueda de cadenas estándar como Knuth-Morris-Pratt o Boyer-Moore, todos los cuales son lineales en la longitud del pajar.

Sin embargo, si conocemos la matriz de sufijos para el pajar, acabamos de ordenar todos sus sufijos (y, por lo tanto, casi ordenamos todas las subcadenas posibles). Y buscar en una lista ordenada es fácil, ¿verdad? ¡Podemos usar la búsqueda binaria! Es decir, comenzamos comparando la aguja con el sufijo que aparece en el medio de la matriz de sufijos. Si tenemos suerte y el sufijo actualmente considerado comienza con la aguja, acabamos de encontrar una aparición de la aguja. (Y si hay más ocurrencias, deben corresponder a los sufijos inmediatamente anteriores y / o siguientes). De lo contrario, simplemente procedemos como en una búsqueda binaria estándar: desechamos la primera mitad de los sufijos si la aguja es más grande que el sufijo actual y la segunda mitad en el otro caso.

Usando algunos trucos más (por ejemplo, el cálculo de la matriz de prefijos comunes más largos ), la complejidad temporal de una sola búsqueda se puede reducir a la longitud de la aguja, más el logaritmo del tamaño del pajar.

¿Por qué es esto súper útil? Piense en bioinformática, por ejemplo. Su pajar es un pedazo de ADN: una secuencia de bases muy larga pero fija. Usted calcula su matriz de sufijos una vez. Luego, cada vez que desee encontrar una secuencia particular de bases en su pajar, puede hacer la búsqueda extremadamente rápido, sin siquiera mirar la mayor parte del pajar.

La matriz de sufijos es una estructura de datos. Dada una cadena, si todos los sufijos de esa cadena se ordenan en orden ascendente, la matriz resultante se llama matriz de sufijos (también puede ser una lista).

¿Cómo construir una matriz de sufijos?

El enfoque ingenuo es simple y es un enfoque (n ^ 2 log n). La parte en la que podemos modificar un poco está en la parte de clasificación. Dado que las cadenas que estamos clasificando son en realidad parte de la cadena original y no algunas cadenas aleatorias, podemos hacer uso de esto y hacer una clasificación ordenada de moda (considerando los caracteres en potencias de 2 y agrupación), como la primera ordenación basada en los dos primeros caracteres, luego mejora en los primeros cuatro caracteres y así sucesivamente, hasta que alcancemos una longitud después de la cual se ordenan todas las cadenas.

Este enfoque toma (n log ^ 2 n). [Busque el índice de clasificación en cada paso que se utilizará para ordenar en el siguiente paso. Ya que estaremos formando tuplas de índice de clasificación e índice de clasificación + 2 y clasificación basada en ellas].

Hay ejemplos de código de implementación para este enfoque. Si solo puede rastrear la ejecución una vez con un ejemplo, la obtendrá fácilmente.

La matriz de sufijos es el resultado del recorrido transversal de izquierda a derecha del árbol de sufijos. Por lo tanto, contiene más o menos la misma información que el árbol de sufijos (al menos cuando aumenta la matriz de prefijos comunes más larga) pero en una forma más compacta.

More Interesting

¿Es posible simular / emular / codificar el poder de pensamiento de una CPU en una GPU?

¿Cómo se determina la mejor, la media y la peor información dada sobre lo que devuelve un método después del bucle?

Aprendizaje automático: ¿Cuál es la idea general de por qué minimizar la minimización empírica de riesgos es NP-Complete?

¿Cuál es el mejor algoritmo de programación que hayas creado?

¿Debería seleccionar siempre el algoritmo con el menor orden de complejidad?

¿Cuáles son las desventajas de las funciones recursivas?

¿Cómo funcionan los algoritmos bayesianos para la identificación de spam?

¿Está bien tomar referencias de otras soluciones mientras se resuelve la programación competitiva para un principiante?

¿Cuáles son algunos de los algoritmos de aprendizaje automático sin supervisión utilizados para la detección de spam?

¿Cuál de los siguientes libros es más adecuado para principiantes y más fácil de entender: CLRS o Algorithms by Sedgewick?

¿Qué algoritmo se usa en WhatsApp?

Dada una matriz con 1s y 0s, necesitamos crear una matriz tal que a [i] [j] = 1, si solo cada elemento en la fila i y columna j es 1, de lo contrario 0. Tenemos que usar un espacio constante y tener Una óptima complejidad temporal. ¿Cuáles son algunas posibles soluciones?

¿Se puede implementar una lista vinculada individualmente como una lista doblemente vinculada?

¿Es posible proporcionar un análisis de complejidad para todos los algoritmos en términos de theta?

Si estoy usando Java para la codificación competitiva, ¿tendré problemas de tiempo más tarde por parte de jueces en línea cuando me sumerja en estructuras de datos y algoritmos?