На самом деле вам нужно заботиться только о проверке длины подстроки, равной полной длине строки , деленной на простое число .Причина в том, что если S содержит n копий T, а n не является простым, тогда n = ab, и поэтому S фактически также содержит копии bT (где «bT» означает «T повторено b раз»).Это расширение ответа anijhaw .
int primes[] = { 2, 3, 5, 7, 11, 13, 17 }; /* There are one or two more... ;) */
int nPrimes = sizeof primes / sizeof primes[0];
/* Passing in the string length instead of assuming ASCIIZ strings means we
* don't have to modify the string in-place or allocate memory for new copies
* to handle recursion. */
int is_iterative(char *s, int len) {
int i, j;
for (i = 0; i < nPrimes && primes[i] < len; ++i) {
if (len % primes[i] == 0) {
int sublen = len / primes[i];
/* Is it possible that s consists of repeats of length sublen? */
for (j = sublen; j < len; j += sublen) {
if (memcmp(s, s + j, sublen)) {
break;
}
}
if (j == len) {
/* All length-sublen substrings are equal. We could stop here
* (meaning e.g. "abababab" will report a correct, but
* non-minimal repeated substring of length 4), but let's
* recurse to see if an even shorter repeated substring
* can be found. */
return is_iterative(s, sublen);
}
}
}
return len; /* Could not be broken into shorter, repeated substrings */
}
Обратите внимание, что при повторном поиске, чтобы найти еще более короткие повторяющиеся подстроки, нам не нужно снова проверять всю строку, только первую большуюповторить - так как мы уже установили, что оставшиеся большие повторы, ну, повторы первого.:)