stringtranslate.com

Matriz LCP

En informática , la matriz de prefijos comunes más largos ( matriz LCP ) es una estructura de datos auxiliar de la matriz de sufijos . Almacena las longitudes de los prefijos comunes más largos (LCP) entre todos los pares de sufijos consecutivos en una matriz de sufijos ordenada.

Por ejemplo, si A  := [ab,desde,Abaab,b,bebé] es una matriz de sufijos, el prefijo común más largo entre A [1] =aby A [2] =desdeesaque tiene una longitud de 1, por lo que H [2] = 1 en la matriz LCP H . Asimismo, el LCP de A [2] =desdey A [3] =Abaabesdesde, por lo que H [3] = 2.

Aumentar la matriz de sufijos con la matriz LCP permite simular de manera eficiente recorridos de arriba hacia abajo y de abajo hacia arriba del árbol de sufijos , [1] [2] acelera la coincidencia de patrones en la matriz de sufijos [3] y es un requisito previo para los árboles de sufijos comprimidos. [4]

Historia

La matriz LCP fue introducida en 1993 por Udi Manber y Gene Myers junto con la matriz de sufijos para mejorar el tiempo de ejecución de su algoritmo de búsqueda de cadenas. [3]

Definición

Sea la matriz de sufijos de la cadena de longitud , donde es una letra centinela que es única y lexicográficamente más pequeña que cualquier otro carácter. Sea la subcadena de que va de a . Por lo tanto, es el sufijo más pequeño de .

Sea la longitud del prefijo común más largo entre dos cadenas y . Entonces, la matriz LCP es una matriz de números enteros de tamaño tal que no está definida y para cada . Por lo tanto, almacena la longitud del prefijo común más largo del sufijo lexicográficamente más pequeño y su predecesor en la matriz de sufijos.

Diferencia entre matriz LCP y matriz de sufijos:

Ejemplo

Considere la cadena :

y su matriz de sufijos ordenados correspondiente  :

Matriz de sufijos con sufijos escritos debajo verticalmente:

Luego, la matriz LCP se construye comparando sufijos lexicográficamente consecutivos para determinar su prefijo común más largo:

Por ejemplo, ¿la longitud del prefijo común más largo que comparten los sufijos y es ? Nótese que no está definido, ya que no existe un sufijo lexicográficamente más pequeño.

Algoritmos de construcción eficientes

Los algoritmos de construcción de matrices LCP se pueden dividir en dos categorías diferentes: algoritmos que calculan la matriz LCP como un subproducto de la matriz de sufijos y algoritmos que utilizan una matriz de sufijos ya construida para calcular los valores LCP.

Manber y Myers (1993) proporcionan un algoritmo para calcular la matriz LCP junto con la matriz de sufijos en el tiempo. Kärkkäinen y Sanders (2003) muestran que también es posible modificar su algoritmo de tiempo de modo que calcule también la matriz LCP. Kasai et al. (2001) presentan el primer algoritmo de tiempo (FLAAP) que calcula la matriz LCP dado el texto y la matriz de sufijos.

Suponiendo que cada símbolo de texto ocupa un byte y cada entrada del sufijo o matriz LCP ocupa 4 bytes, el principal inconveniente de su algoritmo es una gran ocupación de espacio de bytes, mientras que la salida original (texto, matriz de sufijos, matriz LCP) solo ocupa bytes. Por lo tanto, Manzini (2004) creó una versión refinada del algoritmo de Kasai et al. (2001) (lcp9) y redujo la ocupación de espacio a bytes. Kärkkäinen, Manzini y Puglisi (2009) proporcionan otro refinamiento del algoritmo de Kasai ( -algoritmo) que mejora el tiempo de ejecución. En lugar de la matriz LCP real, este algoritmo construye la matriz LCP permutada (PLCP), en la que los valores aparecen en orden de texto en lugar de orden lexicográfico.

Gog y Ohlebusch (2011) proporcionan dos algoritmos que, aunque teóricamente son lentos ( ), en la práctica son más rápidos que los algoritmos mencionados anteriormente.

A partir de 2012 , el algoritmo de construcción de matrices LCP en tiempo lineal más rápido en la actualidad se debe a Fischer (2011), que a su vez se basa en uno de los algoritmos de construcción de matrices de sufijos más rápidos (SA-IS) de Nong, Zhang y Chan (2009). Fischer y Kurpicz (2017) basado en DivSufSort de Yuta Mori es aún más rápido.

Aplicaciones

Como señalan Abouelhoda, Kurtz y Ohlebusch (2004), varios problemas de procesamiento de cadenas se pueden resolver mediante los siguientes tipos de recorridos de árboles :

Kasai et al. (2001) muestran cómo simular un recorrido ascendente del árbol de sufijos utilizando únicamente la matriz de sufijos y la matriz LCP. Abouelhoda, Kurtz y Ohlebusch (2004) mejoran la matriz de sufijos con la matriz LCP y estructuras de datos adicionales y describen cómo se puede utilizar esta matriz de sufijos mejorada para simular los tres tipos de recorridos del árbol de sufijos. Fischer y Heun (2007) reducen los requisitos de espacio de la matriz de sufijos mejorada mediante el preprocesamiento de la matriz LCP para consultas de rango mínimo . Por lo tanto, todos los problemas que se pueden resolver mediante algoritmos de árbol de sufijos también se pueden resolver utilizando la matriz de sufijos mejorada . [2]

Decidir si un patrón de longitud es una subcadena de una cadena de longitud lleva tiempo si solo se utiliza la matriz de sufijos. Al utilizar además la información LCP, este límite se puede mejorar en tiempo. [3] Abouelhoda, Kurtz y Ohlebusch (2004) muestran cómo mejorar este tiempo de ejecución aún más para lograr un tiempo óptimo. Por lo tanto, utilizando la matriz de sufijos y la información de la matriz LCP, la consulta de decisión se puede responder tan rápido como utilizando el árbol de sufijos .

La matriz LCP también es una parte esencial de los árboles de sufijos comprimidos que proporcionan una funcionalidad completa de árboles de sufijos como enlaces de sufijos y consultas de ancestro común más bajo . [5] [6] Además, se puede utilizar junto con la matriz de sufijos para calcular la factorización Lempel-Ziv LZ77 en el tiempo. [2] [7] [8] [9]

El problema de la subcadena repetida más larga para una cadena de longitud se puede resolver en el tiempo utilizando tanto la matriz de sufijos como la matriz LCP. Es suficiente realizar un escaneo lineal a través de la matriz LCP para encontrar su valor máximo y el índice correspondiente donde se almacena. La subcadena más larga que aparece al menos dos veces se da entonces por .

El resto de esta sección explica dos aplicaciones de la matriz LCP con más detalle: cómo se pueden usar la matriz de sufijos y la matriz LCP de una cadena para construir el árbol de sufijos correspondiente y cómo es posible responder consultas LCP para sufijos arbitrarios utilizando consultas de rango mínimo en la matriz LCP.

Encuentra el número de ocurrencias de un patrón

Para encontrar el número de ocurrencias de una cadena dada (longitud ) en un texto (longitud ), [3]

El problema con el uso de la búsqueda binaria estándar (sin la información LCP) es que en cada una de las comparaciones que se deben realizar, comparamos P con la entrada actual de la matriz de sufijos, lo que significa una comparación de cadena completa de hasta m caracteres. Por lo tanto, la complejidad es .

La matriz LCP-LR ayuda a mejorar esto de la siguiente manera:

En cualquier punto durante el algoritmo de búsqueda binaria, consideramos, como es habitual, un rango de la matriz de sufijos y su punto central , y decidimos si continuamos nuestra búsqueda en el subrango izquierdo o en el subrango derecho . Para tomar la decisión, comparamos con la cadena en . Si es idéntico a , nuestra búsqueda está completa. Pero si no, ya hemos comparado los primeros caracteres de y luego decidimos si es lexicográficamente menor o mayor que . Supongamos que el resultado es que es mayor que . Entonces, en el siguiente paso, consideramos y un nuevo punto central en el medio:

 Yo ...... Yo ...... R | sabemos: lcp(P,M)==k

El truco ahora es que LCP-LR está precalculado de tal manera que una búsqueda nos indica el prefijo común más largo de y , .

Ya sabemos (por el paso anterior) que sí tiene un prefijo de caracteres en común con : . Ahora hay tres posibilidades:

El efecto general es que ningún carácter de se compara con ningún carácter del texto más de una vez (para más detalles, consulte [3] ). El número total de comparaciones de caracteres está limitado por , por lo que la complejidad total es de hecho .

Aún necesitamos calcular previamente LCP-LR para que pueda decirnos a tiempo el lcp entre dos entradas cualesquiera de la matriz de sufijos. Sabemos que la matriz LCP estándar nos da el lcp de entradas consecutivas solamente, es decir, para cualquier . Sin embargo, y en la descripción anterior no son necesariamente entradas consecutivas.

La clave para esto es darse cuenta de que solo ciertos rangos aparecerán alguna vez durante la búsqueda binaria: siempre comienza con y divide eso en el centro, y luego continúa hacia la izquierda o la derecha y divide esa mitad nuevamente y así sucesivamente. Otra forma de verlo es: cada entrada de la matriz de sufijos aparece como punto central de exactamente un rango posible durante la búsqueda binaria. Por lo tanto, hay exactamente N rangos distintos que posiblemente puedan desempeñar un papel durante la búsqueda binaria, y basta con precalcular y para esos rangos posibles. Por lo tanto, son valores precalculados distintos, por lo tanto, LCP-LR es de tamaño.

Además, existe un algoritmo recursivo sencillo para calcular los valores de LCP-LR en el tiempo a partir de la matriz LCP estándar.

En resumen:

Construcción de árboles de sufijos

Dada la matriz de sufijos y la matriz LCP de una cadena de longitud , su árbol de sufijos se puede construir en el tiempo basándose en la siguiente idea: comenzar con el árbol de sufijos parcial para el sufijo lexicográficamente más pequeño e insertar repetidamente los otros sufijos en el orden dado por la matriz de sufijos.

Sea el árbol de sufijos parcial para . Además, sea la longitud de la concatenación de todas las etiquetas de ruta desde la raíz de hasta el nodo .

Caso 1 ( ): Supongamos que los sufijos , y de la cadena ya se han añadido al árbol de sufijos. A continuación, el sufijo se añade al árbol como se muestra en la imagen. La ruta situada más a la derecha se resalta en rojo.

Comience con , el árbol que consta solo de la raíz. Para insertar en , camine hacia arriba por el camino más a la derecha comenzando en la hoja recientemente insertada hasta la raíz, hasta llegar al nodo más profundo con .

Es necesario distinguir dos casos:

  1. Eliminar el borde .
  2. Agregue un nuevo nodo interno y una nueva arista con la etiqueta . La nueva etiqueta consta de los caracteres faltantes del prefijo común más largo de y . Por lo tanto, la concatenación de las etiquetas de la ruta de la raíz a la ruta ahora muestra el prefijo común más largo de y .
  3. Conéctese al nodo interno recién creado mediante un borde que tenga la etiqueta . La nueva etiqueta consta de los caracteres restantes del borde eliminado que no se usaron como etiqueta del borde .
  4. Agregue una nueva hoja y conéctela al nuevo nodo interno mediante una arista etiquetada como . Por lo tanto, la etiqueta de la arista consta de los caracteres restantes del sufijo que aún no están representados por la concatenación de las etiquetas de la ruta de la raíz a la raíz.
  5. Esto crea el árbol de sufijos parcial .

Un argumento de amortización simple muestra que el tiempo de ejecución de este algoritmo está limitado por :

Los nodos que se recorren paso a paso caminando por el camino más a la derecha de (aparte del último nodo ) se eliminan del camino más a la derecha cuando se agrega al árbol como una nueva hoja. Estos nodos nunca se volverán a recorrer en todos los pasos posteriores . Por lo tanto, se recorrerán nodos como máximo en total.

Consultas LCP para sufijos arbitrarios

La matriz LCP solo contiene la longitud del prefijo común más largo de cada par de sufijos consecutivos en la matriz de sufijos . Sin embargo, con la ayuda de la matriz de sufijos inversa ( , es decir, el sufijo que comienza en la posición en se almacena en la posición en ) y consultas mínimas de rango de tiempo constante en , es posible determinar la longitud del prefijo común más largo de sufijos arbitrarios en el tiempo.

Debido al orden lexicográfico de la matriz de sufijos, cada prefijo común de los sufijos y tiene que ser un prefijo común de todos los sufijos entre la posición de en la matriz de sufijos y la posición de en la matriz de sufijos . Por lo tanto, la longitud del prefijo más largo que comparten todos estos sufijos es el valor mínimo en el intervalo . Este valor se puede encontrar en tiempo constante si se preprocesa para consultas de rango mínimo.

Así, dada una cadena de longitud y dos posiciones arbitrarias en la cadena con , la longitud del prefijo común más largo de los sufijos y se puede calcular de la siguiente manera: .

Notas

  1. ^ Kasai y otros 2001.
  2. ^ abc Abouelhoda, Kurtz y Ohlebusch 2004.
  3. ^ abcde Manber y Myers 1993.
  4. ^ Ohlebusch, Fischer y Gog 2010.
  5. ^ Sadakane 2007.
  6. ^ Fischer, Mäkinen y Navarro 2009.
  7. ^ Crochemore y Ilie 2008.
  8. ^ Crochemore, Ilie y Smyth 2008.
  9. ^ Chen, Puglisi y Smyth 2008.

Referencias

Enlaces externos