/* 求一个字符串中的最长重复字串 基本思路是利用next数组来实现
next数组的定义 就是 字符串中第J个字符 必有next[J] - 1个重复
字串, 事实上 KMP查找 求模式串next数组 就是指求出模式串J个
字符前 最大的重复子串
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#define __in
#define __out
#define __in__out
#define __DEBUG__XU
typedef struct __MAX_SUB
{
int start;
int len;
int tempstart;
int templen;
}MAX_SUB, *PMAX_SUB;
int GetNext(__out int *next, __in char *substring);
int main(int argc, char **argv)
{
char *string = "ccccabababab";
char *substring;
unsigned int len, sublen;
int *next;
int i;
int flag = 0;
#ifdef __DEBUG__XU
int j;
#endif
MAX_SUB maxsub = {0};
len = strlen(string);
for(i = 1; i < len; i++)
{
if(string[i] != string[0])
{
flag = 1;
break;
}
}
if(!flag)
{
printf("string has only one sort of char/n");
printf("%s", string);
return 0;
}
for(i = 0; i < len; i++)
{
#ifdef __DEBUG__XU
printf("substring first pos: %d/n", i);
#endif
substring = string + i;
sublen = strlen(substring);
next = (int *)malloc(sizeof(int) * (sublen + 1));
maxsub.templen = GetNext(next, substring);
maxsub.tempstart = i;
if(maxsub.templen > maxsub.len)
{
maxsub.len = maxsub.templen;
maxsub.start = maxsub.tempstart;
}
#ifdef __DEBUG__XU
for(j = maxsub.start; j < maxsub.len + maxsub.start; j++)
{
printf("%c", string[j]);
}
printf("/n");
#endif
free(next);
}
}
int GetNext(__out int *next, __in char *substring)
{
char *string;
int k, i;
int max_k;
string = substring;
next[0] = -1;
k = next[0];
i = 0;
max_k = k;
while(i < strlen(substring))
{
if(i + 1 == strlen(substring) )
{
if(substring[k] == substring[i])
goto kmp;
}
if(-1 == k || substring[k] == substring[i])
{
kmp:
i++;
k++;
next[i] = k;
if (k > max_k)
{
max_k = k;
}
}
else
{
k = next[k];
}
}
#ifdef __DEBUG__XU
for(i = 0; i < strlen(substring) + 1; i++)
{
printf("next[%d] = %d ", i, next[i]);
}
printf("/n");
getchar();
#endif
return max_k;
}