D'abord, je crois que votre code contient un bogue. La dernière ligne doit être return p;
. Je crois que je détiens l'indice du décalage cyclique lexicographiquement le plus petit et p le plus petit décalage correspondant. Je pense aussi que votre condition d'arrêt est trop faible, c'est-à-dire que vous faites trop de vérifications après avoir trouvé une correspondance, mais je ne suis pas sûr de ce que cela devrait être. Notez que i et j avancent seulement et que i est toujours inférieur à j. Nous recherchons une chaîne qui correspond à la chaîne commençant par i, et nous essayons de la faire correspondre avec une chaîne qui commence à j. Nous faisons cela en comparant le caractère k'th de chaque chaîne tout en augmentant k (tant qu'ils correspondent). Notez que nous ne changeons que i si nous déterminons que la chaîne commençant par j est lexicographiquement inférieure à la chaîne commençant par j, puis nous définissons i et j et réinitialisons k et p à leurs valeurs initiales.
Je n'ai pas le temps pour une analyse détaillée, mais il semble que
- i = le début du décalage cyclique plus petit lexicographique
- j = le début du décalage cyclique nous correspondant contre la déplacer à partir de i
- k = le caractère dans une chaîne i et j actuellement à l'étude (les chaînes correspondent aux positions 1 à k-1
- p = le décalage cyclique considéré (i crois p représente préfixe)
Modifier Allant plus loin
cette section de code
if ((a=x[(i+k-1)%l])>(b=x[(j+k-1)%l])) {
i=j++;
k=p=1;
Déplace le début de la comparaison à une chaîne lexicographique plus tôt lorsque nous trouvons un et Réinitialise tout le reste.
cette section
} else if (a<b) {
j+=k;
k=1;
p=j-i;
est la partie la plus délicate. Nous avons trouvé une discordance qui est lexicographiquement plus tard que notre chaîne de référence, donc nous passons à la fin du texte correspondant jusqu'à présent, et commençons à correspondre à partir de là. Nous augmentons aussi p (notre foulée). Pourquoi pouvons-nous sauter tous les points de départ entre j et j + k? C'est parce que la chaîne commençant par i est la plus petite lexicographiquement vue, et si la queue de la chaîne j courante est plus grande que la chaîne à i alors tout suffixe de la chaîne à j sera plus grand que la chaîne à i.
Enfin
} else if (a==b && k!=p) {
k++;
} else {
j+=p;
k=1;
ce juste vérifie que la chaîne de longueur p à partir de i répétitions.Nous procédons en incrémentant k jusqu'à k == p
, en vérifiant que le caractère k'th de la chaîne commençant par i est égal au caractère k'th de la chaîne commençant en j. Une fois que k atteint p, nous recommençons le balayage à l'occurrence supposée suivante de la chaîne.
Encore d'autres éditer pour tenter de répondre aux questions de jethro.
Premier: le k != p
dans else if (a==b && k!=p)
Ici, nous avons une correspondance en ce que le k'th et tous les caractères précédents dans les chaînes commençant par i et j sont égaux. La variable p représente la longueur que nous pensons que la chaîne répétée est. Lorsque k != p
, en fait k < p
, nous nous assurons que les caractères p sur la chaîne commençant par i sont les mêmes que les p caractères de la chaîne commençant par j. Quand k == p
(le dernier) nous devrions être à un point où la chaîne commençant à j + k
ressemble à la chaîne commençant par j, donc nous augmentons j par p et redéfinissons k à 1 et revenons à comparer les deux chaînes.
Deuxièmement: Oui, je crois que vous avez raison, il devrait retourner i. Je comprends mal le sens de « décalage cyclique minimum »
Il serait plus facile de lire si ce ne sont pas écrits un style si horriblement dense (déplacer des affectations hors condition, une déclaration par ligne, éviter des optimisations prématurées comme remplacer * 2 par shift). – starblue