stringtranslate.com

Rotación de cadenas lexicográficamente mínima

En informática , la rotación de cadena lexicográficamente mínima o la subcadena lexicográficamente menos circular es el problema de encontrar la rotación de una cadena que posee el orden lexicográfico más bajo de todas esas rotaciones. Por ejemplo, la rotación lexicográfica mínima de "bbaaccaadd" sería "aaccaaddbb". Es posible que una cadena tenga múltiples rotaciones lexicográficamente mínimas, pero para la mayoría de las aplicaciones esto no importa ya que las rotaciones deben ser equivalentes. Encontrar la rotación lexicográficamente mínima es útil como forma de normalizar cadenas. Si las cadenas representan estructuras potencialmente isomórficas , como gráficos , la normalización de esta manera permite una verificación de igualdad simple. [1] Un truco de implementación común cuando se trata de cadenas circulares es concatenar la cadena consigo misma en lugar de tener que realizar aritmética modular en los índices de la cadena.

Algoritmos

El algoritmo ingenuo

El algoritmo ingenuo para encontrar la rotación lexicográficamente mínima de una cadena es iterar a través de rotaciones sucesivas mientras se realiza un seguimiento de la rotación lexicográficamente mínima encontrada. Si la cadena tiene una longitud n , este algoritmo se ejecuta en tiempo O ( n 2 ) en el peor de los casos.

Algoritmo de Booth

Booth (1980) propuso un algoritmo eficiente. [2] El algoritmo utiliza una función de preprocesamiento modificada del algoritmo de búsqueda de cadenas Knuth-Morris-Pratt . La función de falla para la cadena se calcula normalmente, pero la cadena se gira durante el cálculo, por lo que algunos índices deben calcularse más de una vez a medida que se ajustan. Una vez que todos los índices de la función de falla se han calculado exitosamente sin que la cadena vuelva a girar, se sabe que se encuentra la rotación lexicográfica mínima y se devuelve su índice inicial. La exactitud del algoritmo es algo difícil de entender, pero es fácil de implementar.

def  less_rotation ( s :  str )  ->  int : """Algoritmo lexicográficamente mínimo de rotación de cadenas de Booth.""" n = len ( s ) f = [ - 1 ] * ( 2 * n ) k = 0 para j en el rango ( 1 , 2 * n ): i = f [ j - k - 1 ] mientras i != - 1 y s [ j % n ] != s [( k + i + 1 ) % n ]: si s [ j % n ] < s [( k + i + 1 ) % n ]: k = j - i - 1 i = f [ i ] si i == - 1 y s [ j % n ] != s [( k + i + 1 ) % n ]: si s [ j % n ] < s [( k + i + 1 ) % n ]: k = j f [ j - k ] = - 1 más : f [ j - k ] = i + 1 vuelta k                                                                                                                

Es interesante que eliminar todas las líneas de código que modifican el valor de k da como resultado la función de preprocesamiento original de Knuth-Morris-Pratt, ya que k (que representa la rotación) permanecerá cero. El algoritmo de Booth se ejecuta en el tiempo, donde n es la longitud de la cadena. El algoritmo realiza como máximo comparaciones en el peor de los casos y requiere una memoria auxiliar de longitud n para contener la tabla de funciones de falla.

Algoritmo de canonización rápida de Shiloach

Shiloach (1981) [3] propuso un algoritmo que mejoraba el resultado de Booth en términos de rendimiento. Se observó que si hay q rotaciones lexicográficamente mínimas equivalentes de una cadena de longitud n , entonces la cadena debe consistir en q subcadenas iguales de longitud . El algoritmo sólo requiere comparaciones y espacio constante en el peor de los casos.

El algoritmo se divide en dos fases. La primera fase es un tamiz rápido que descarta índices que obviamente no son lugares de partida para la rotación lexicográficamente mínima. La segunda fase encuentra entonces el índice de inicio de rotación lexicográficamente mínimo a partir de los índices que quedan.

Algoritmo de factorización Lyndon de Duval

Duval (1983) [4] propuso un algoritmo eficiente que implica la factorización de la cadena en sus palabras Lyndon componentes , que se ejecuta en tiempo lineal con un requisito de memoria constante.

Variantes

Shiloach (1979) [5] propuso un algoritmo para comparar eficientemente la igualdad de dos cadenas circulares sin un requisito de normalización. Una aplicación adicional que surge del algoritmo es la generación rápida de determinadas estructuras químicas sin repeticiones.

Ver también

Referencias

  1. ^ Cabina de Kellogg S.; Colbourn, Charles J. (1980). "Algoritmos de automorfismo de tiempo lineal para árboles, gráficos de intervalos y gráficos planos". Revista SIAM de Computación . 10 (1). Sociedad de Matemáticas Industriales y Aplicadas: 203–225. doi :10.1137/0210015. ISSN  0097-5397.
  2. ^ Stand de Kellogg S. (1980). "Subcadenas lexicográficamente menos circulares". Cartas de procesamiento de información . 10 (4-5). Elsevier: 240–242. doi :10.1016/0020-0190(80)90149-0. ISSN  0020-0190.
  3. ^ Yossi Shiloaj (1981). "Rápida canonización de cuerdas circulares". Revista de algoritmos . 2 (2). Elsevier: 107-121. doi :10.1016/0196-6774(81)90013-4. ISSN  0196-6774.
  4. ^ Jean-Pierre Duval (1983). "Factorizar palabras sobre un alfabeto ordenado". Revista de algoritmos . 8 (8). Elsevier: 363–381. doi :10.1016/0196-6774(83)90017-2. ISSN  0196-6774.
  5. ^ Yossi Shiloaj (1979). "Un algoritmo rápido de verificación de equivalencia para listas circulares". Cartas de procesamiento de información . 8 (5). Elsevier: 236–238. doi :10.1016/0020-0190(79)90114-5. ISSN  0020-0190.