stringtranslate.com

matriz LCP

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

Por ejemplo, si A  := [ab,ab,abaab,b,baab] es una matriz de sufijos, el prefijo común más largo entre A [1] =aby A [2] =abesaque tiene longitud 1, por lo que H [ 2 ] = 1 en la matriz LCP H. Asimismo, el LCP de A [2] =aby A [3] =abaabesab, entonces H [3] = 2.

Aumentar la matriz de sufijos con la matriz LCP permite simular eficientemente 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 el sufijo comprimido árboles. [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. Denotemos la subcadena que va desde hasta . Por tanto, es el décimo sufijo más pequeño de .

Denotemos la longitud del prefijo común más largo entre dos cadenas y . Entonces la matriz LCP es una matriz entera de tamaño tal que no está definida y es 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 correspondiente matriz de sufijos ordenados  :

Matriz de sufijos con los sufijos escritos debajo verticalmente:

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

Entonces, por ejemplo, la longitud del prefijo común más largo es compartida por los sufijos y . Tenga en cuenta 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 de 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 también calcule 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 mayor inconveniente de su algoritmo es una gran ocupación de espacio de bytes, mientras que la salida original (texto, matriz de sufijos, matriz LCP) sólo ocupa bytes. Por tanto, Manzini (2004) creó una versión refinada del algoritmo de Kasai et al. (2001) (lcp9) y redujo la ocupación del 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 & Ohlebusch (2011) proporcionan dos algoritmos que, aunque teóricamente eran lentos ( ), en la práctica eran 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 actualmente se debe a Fischer (2011), que a su vez se basa en uno de los algoritmos de construcción de matrices de sufijos (SA-IS) más rápidos de Nong, Zhang y Chan (2009). . Fischer & Kurpicz (2017), basado en DivSufSort de Yuta Mori, es aún más rápido.

Aplicaciones

Como señalaron 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 sólo 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 esta matriz de sufijos mejorada se puede utilizar para simular los tres tipos de recorridos de árboles de sufijos. Fischer y Heun (2007) reducen los requisitos de espacio de la matriz de sufijos mejorada preprocesando la matriz LCP para consultas de rango mínimo . Por lo tanto, todos los problemas que pueden resolverse mediante algoritmos de árbol de sufijos también pueden resolverse 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 adicionalmente la información LCP, este límite se puede mejorar con el tiempo. [3] Abouelhoda, Kurtz y Ohlebusch (2004) muestran cómo mejorar aún más este tiempo de carrera para lograr un tiempo óptimo. Por lo tanto, utilizando la información de la matriz de sufijos y la matriz LCP, la consulta de decisión se puede responder tan rápido como usando el árbol de sufijos .

La matriz LCP también es una parte esencial de los árboles de sufijos comprimidos que proporcionan una funcionalidad completa del árbol 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 subcadena repetida más larga para una cadena de longitud se puede resolver a 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 está almacenado. La subcadena más larga que aparece al menos dos veces viene dada 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 usando el rango. consultas mínimas en la matriz LCP.

Encuentra el número de apariciones de un patrón.

Para encontrar el número de apariciones de una cadena determinada (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 necesarias, comparamos P con la entrada actual de la matriz de sufijos, lo que significa una comparación de cadena completa de hasta m caracteres. Entonces 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 de costumbre, 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 hemos decidido si es lexicográficamente menor o mayor que . Supongamos que el resultado es mayor que . Entonces, en el siguiente paso, consideramos un nuevo punto central en el medio:

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

El truco ahora es que LCP-LR se calcula previamente de modo que una búsqueda nos indique el prefijo común más largo de y , .

Ya sabemos (por el paso anterior) que 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. El número total de comparaciones de caracteres está limitado por , por lo que la complejidad total sí lo está .

Todavía necesitamos precalcular 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 proporciona el lcp de entradas consecutivas únicamente, es decir, para cualquiera . Sin embargo, y en la descripción anterior no hay necesariamente entradas consecutivas.

La clave para esto es darse cuenta de que solo ciertos rangos ocurrirán durante la búsqueda binaria: siempre comienza y lo divide en el centro, y luego continúa hacia la izquierda o hacia la derecha y divide esa mitad nuevamente y así sucesivamente. Otra forma de verlo es: cada entrada de la matriz de sufijos ocurre 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. Entonces se trata de valores precalculados distintos, por lo tanto, LCP-LR tiene 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.

Para resumir:

Construcción de árbol 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: comience con el árbol de sufijos parcial para el sufijo lexicográficamente más pequeño e inserte 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 hasta el nodo .

Caso 1 ( ) : Supongamos que los sufijos , y de la cadena ya están agregados al árbol de sufijos. Luego se agrega el sufijo al árbol como se muestra en la imagen. El camino más a la derecha está resaltado en rojo.

Comience con , el árbol que consta únicamente de la raíz. Para insertar en , recorra el camino más a la derecha comenzando en la hoja recientemente insertada hasta la raíz, hasta llegar al nodo más profundo .

Debemos distinguir dos casos:

  1. Eliminar el borde .
  2. Agregue un nuevo nodo interno y un nuevo borde con etiqueta . La nueva etiqueta consta de los caracteres que faltan del prefijo común más largo y . Por lo tanto, la concatenación de las etiquetas 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 etiquetado . La nueva etiqueta consta de los caracteres restantes del borde eliminado que no se utilizaron como etiqueta del borde .
  4. Agréguelo como una nueva hoja y conéctelo al nuevo nodo interno mediante un borde etiquetado . Por lo tanto, la etiqueta de borde 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 raíz a ruta.
  5. Esto crea el árbol de sufijos parciales .

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 recorriendo el camino más a la derecha (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 serán atravesados ​​nuevamente en todos los pasos posteriores . Por lo tanto, como máximo los nodos se recorrerán 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. a 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 compartido por 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 se puede calcular de la siguiente manera: .

Notas

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

Referencias

enlaces externos