Skip to content

Instantly share code, notes, and snippets.

@MaskRay
Created February 4, 2014 13:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MaskRay/8803371 to your computer and use it in GitHub Desktop.
Save MaskRay/8803371 to your computer and use it in GitHub Desktop.
Lyndon word or lexicographically minimal string rotation
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 1213;
char a[N+1];
// n > 0
int lyndon_word(const char *a, int n)
{
int i = 0, j = 1, k;
while (j < n) {
// Invariant: i < j and indices in [0,j) \ i cannot be the first optimum
for (k = 0; k < n && a[(i+k)%n] == a[(j+k)%n]; k++);
if (a[(i+k)%n] <= a[(j+k)%n]) {
// if k < n
// foreach p in [j,j+k], s_p > s_{p-(j-i)}
// => [j,j+k] are all suboptimal
// => indices in [0,j+k+1) \ i are suboptimal
// else
// None of [j,j+k] is the first optimum
j += k+1;
} else {
// foreach p in [i,i+k], s_p > s_{p+(j-i)}
// => [i,i+k] are all suboptimal
// => [0,j) and [0,i+k+1) are suboptimal
// if i+k+1 < j
// j < j+1 and indices in [0,j+1) \ j are suboptimal
// else
// i+k+1 < i+k+2 and indices in [0,i+k+2) \ (i+k+1) are suboptimal
i += k+1;
if (i < j)
i = j++;
else
j = i+1;
}
}
// j >= n => [0,n) \ i cannot be the first optimum
return i;
}
int main()
{
while (gets(a)) {
printf("%d\n", lyndon_word(a, (int)strlen(a)));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment