stringtranslate.com

Algoritmo Raita

En informática, el algoritmo Raita es un algoritmo de búsqueda de cadenas que mejora el rendimiento del algoritmo Boyer–Moore–Horspool . Este algoritmo preprocesa la cadena que se busca en busca del patrón, lo que es similar al algoritmo de búsqueda de cadenas Boyer–Moore . El patrón de búsqueda de una subcadena particular en una cadena dada es diferente del algoritmo Boyer–Moore–Horspool. Este algoritmo fue publicado por Timo Raita en 1991. [1]

Descripción

El algoritmo Raita busca un patrón "P" en un texto "T" determinado comparando cada carácter del patrón en el texto determinado. La búsqueda se realizará de la siguiente manera. La ventana para un texto "T" se define como la longitud de "P".

  1. El primer y último carácter del patrón se compara con el carácter más a la derecha de la ventana.
  2. Si hay una coincidencia, el primer carácter del patrón se compara con el carácter más a la izquierda de la ventana.
  3. Si coinciden nuevamente, compara el carácter medio del patrón con el carácter medio de la ventana.

Si todo en la comprobación previa es correcto, entonces la comparación original comienza desde el segundo carácter hasta el penúltimo. Si hay una discrepancia en cualquier etapa del algoritmo, se ejecuta la función de desplazamiento de caracteres incorrectos que se calculó en la fase de preprocesamiento. La función de desplazamiento de caracteres incorrectos es idéntica a la propuesta en el algoritmo de Boyer–Moore–Horspool. [1]

Una formulación moderna de una comprobación previa similar se encuentra en std::string::find, un comparador de cadenas lineal/cuadrático, en libc++ y libstdc++. Suponiendo una versión bien optimizada de memcmp, no omitir caracteres en la "comparación original" tiende a ser más eficiente ya que es probable que el patrón esté alineado. [2]

Código C para el algoritmo Raita

#include <limites.h> #include <stddef.h>  #define ALPHABET_SIZE (1 << CHAR_BITS) /* normalmente 256 *//* Preprocesamiento: la tabla de coincidencias incorrectas de BMH. */ static inline void preBmBc ( char * pat , size_t lpat , ptrdiff_t bmBc []) { size_t i ; for ( i = 0 ; i < ALPHABET_SIZE ; ++ i ) bmBc [ i ] = lpat ; for ( i = 0 ; i < lpat - 1 ; ++ i ) bmBc [ pat [ i ]] = lpat - i - 1 ; }                                       void RAITA ( char * pat , tamaño_t lpat , char * s , tamaño_t n ) { ptrdiff_t bmBc [ TAMAÑO_ALFABETO ];            /* Casos extremos rápidos. */ if ( lpat == 0 || lpat > n ) return ;          si ( lpat == 1 ) { char * match_ptr = s ; mientras ( match_ptr < s + n ) { match_ptr = memchr ( match_ptr , pat [ 0 ], n - ( match_ptr - s )); si ( match_ptr != NULL ) { SALIDA ( match_ptr - s ); match_ptr ++ ; } de lo contrario devolver ; } }                                       preBmBc ( palmadita , lpat , bmBc );   /* La ventana previa al partido. */ char firstCh = pat [ 0 ]; char middleCh = palmadita [ lpat / 2 ]; char lastCh = palmadita [ lpat - 1 ];                 /* Búsqueda */ ptrdiff_t j = 0 ; while ( j <= n - m ) { char c = s [ j + lpat - 1 ]; /* Esto podría dañar la localidad de los datos en patrones largos. Para estos, considere reducir  * la cantidad de pruebas previas o usar índices más agrupados. */ if ( lastCh == c && middleCh == s [ j + lpat / 2 ] && firstCh == s [ j ] && memcmp ( & pat [ 1 ], & s [ j + 1 ], lpat - 2 ) == 0 ) OUTPUT ( j ); j ​​+= bmBc [ c ]; } }                                                 

Ejemplo

Patrón: abddb

Texto:abbaabaabddbabadbb

Etapa de preprocesamiento:

 desde 4 3 1
Intento 1: abbaabaabddbabadbb ....b Desplazamiento por 4 (bmBc[a])

Comparación del último carácter del patrón con el carácter más a la derecha de la ventana. No coincide y se desplaza en 4 puntos según el valor de la etapa de preprocesamiento.

Intento 2: abbaabaabddbabadbb AdB Desplazamiento por 3 (bmBc[b])

Aquí, el último y el primer carácter del patrón coinciden, pero el carácter del medio no coincide, por lo que el patrón cambia según la etapa de preprocesamiento.

Intento 3: abbaabaabddbabadbb ABDDB Desplazamiento por 3 (bmBc[b])

Encontramos una coincidencia exacta aquí, pero el algoritmo continúa hasta que no puede avanzar más.

Intento 4: abbaabaABDDBabadbb ....b Desplazamiento por 4 (bmBc[a])

En esta etapa, necesitamos desplazarnos 4 veces y no podemos mover el patrón 4 veces. Por lo tanto, el algoritmo finaliza. Las letras en mayúsculas son exactamente iguales al patrón del texto.

Complejidad

  1. La etapa de preprocesamiento toma un tiempo O(m), donde "m" es la longitud del patrón "P".
  2. La etapa de búsqueda tiene una complejidad temporal de O(mn), donde "n" es la longitud del texto "T".

Véase también

Referencias

  1. ^ ab RAITA T., 1992, Ajuste del algoritmo de búsqueda de cadenas Boyer–Moore–Horspool, Software - Práctica y experiencia, 22(10):879-884 [1]
  2. ^ "⚙ D27068 Mejora string::find". Revisión de código de LLVM .

Enlaces externos