En primer lugar, creo que su código tiene un error. La última línea debe ser return p;
. Creo que tengo el índice del desplazamiento cíclico lexicográficamente más pequeño, y p tiene el cambio más pequeño que coincide. También creo que su condición de detención es demasiado débil, es decir, usted está haciendo demasiadas comprobaciones después de haber encontrado una coincidencia, pero no estoy seguro exactamente de qué se trata.
Tenga en cuenta que i y j solo avanzan y que siempre es menor que j. Estamos buscando una cadena que coincida con la cadena que comienza en i, y estamos tratando de hacerla coincidir con una cadena que comienza en j. Hacemos esto comparando el carácter k'th de cada cuerda mientras aumentamos k (siempre que coincidan). Tenga en cuenta que solo cambiamos i si determinamos que la cadena que comienza en j es lexicográficamente menor que la cadena que comienza en j, y luego configuramos i a j y restablecemos k y p a sus valores iniciales.
no tengo tiempo para un análisis detallado, pero parece que
- i = el inicio de la lexicográfico desplazamiento cíclico más pequeño
- j = el inicio del desplazamiento cíclico estamos igualando en contra de la cambiar a partir de i
- k = el carácter en las cadenas de i y j actualmente bajo consideración (el partido cadenas en las posiciones 1 a K-1
- p = el desplazamiento cíclico bajo consideración (i creo p significa prefijo)
Editar Yendo más lejos
esta sección del código
if ((a=x[(i+k-1)%l])>(b=x[(j+k-1)%l])) {
i=j++;
k=p=1;
Mueve el inicio de la comparación con una cadena lexicográfico antes, cuando nos encontramos con uno y reinicializa todo lo demás.
esta sección
} else if (a<b) {
j+=k;
k=1;
p=j-i;
es la parte difícil. Hemos encontrado un desajuste que es lexicográficamente posterior a nuestra cadena de referencia, por lo que saltamos hasta el final del texto coincidente hasta el momento, y comenzamos a buscar desde allí. También aumentamos p (nuestro paso). ¿Por qué podemos omitir todos los puntos de partida entre j y j + k? Esto se debe a que la cadena que comienza con i es lexicográficamente la más pequeña vista, y si la cola de la cadena j actual es mayor que la cadena en i, entonces cualquier sufijo de la cadena en j será mayor que la cadena en i.
Finalmente
} else if (a==b && k!=p) {
k++;
} else {
j+=p;
k=1;
esto sólo comprueba que la cadena de longitud p a partir de i repeticiones.
** * hacer otras modificaciones Hacemos esto mediante el incremento de k hasta k == p
, comprobando que el carácter k-ésima de la cadena a partir de i es igual a k-ésima del carácter de la cadena a partir de j. Una vez que k alcanza p, comenzamos a escanear de nuevo en la siguiente supuesta ocurrencia de la cadena.
Edite aún más para intentar responder a las preguntas de jethro.
Primero: el k != p
en else if (a==b && k!=p)
Aquí tenemos una coincidencia en que la k'th y todos los caracteres anteriores en las cadenas que comienzan en i y j son iguales. La variable p representa la longitud que creemos que es la cadena repetitiva. Cuando k != p
, en realidad k < p
, nos aseguramos de que los caracteres p en la cadena que comienza en i sean los mismos que los caracteres p de la cadena que comienza en j. Cuando k == p
(la última cosa) deberíamos estar en un punto donde la cadena que comienza en j + k
tiene el mismo aspecto que la cadena que comienza en j, entonces aumentamos j por p y ajustamos k a 1 y volvemos a comparar las dos cadenas.
Segundo: Sí, creo que está en lo cierto, debería regresar i. Estaba mal entendido el significado de "desplazamiento cíclico mínimo"
Sería más fácil de leer si no estuviera escrito en un estilo tan horriblemente denso (asignaciones de movimiento fuera de condición, una declaración por línea, evite optimizaciones prematuras como reemplazar * 2 por turno). – starblue