最长重复子串问题

  今天面试被一道没见过的题,完全整闷了。求一段字符串的最长重复子串。后来网上看看博客,竟然可以用KMP写,为自己的无知感到羞愧。好吧,我来学习一下如何用KMP方法解决这样的问题,关键是next的特性来解决这个问题。

#include <iostream>
#include <cstring>
using namespace std;
int Get_next(char *p, int nextval[])
{
    int j = -1;
    nextval[0] = -1;
    int len = strlen(p);
    int i = 0;
    int maxlen = 0;
    while(i < len)
    {
        if(j == -1 || p[i] == p[j])
        {
            i++;
            j++;
            nextval[i] = j;
            if(j > maxlen)   //求其中重复最大的字符串的个数,也就是与前面最前串的重复数
                maxlen = j;
        }
        else
            j = nextval[j];
    }
    return maxlen;
}

int main()
{
    char s[100];
    cin >> s;
    int maxlen = 0;//最大串的个数
    int nextMax; //Get_next函数得到的最大值
    int i;
    int maxIndex;
    int len = strlen(s);
    for(i = 0; i < len-1; i++)
    {
        int *next = new int[len - i];
        nextMax = Get_next(s + i, next);
        if(nextMax > maxlen)
        {
            maxIndex = i;
            maxlen = nextMax;
        }
    }
    cout << "输出最长重复子串:" << endl;
    for(i = 0; i < maxlen; i++)
        cout << s[i + maxIndex];
    cout << endl;
}

  使用KMP的特性来解决这道题,时间复杂度有点高啊。

  事情总有解决的方法,所以就有了后缀数组这一数据结构来解决这个方法。对一个字符串生成相应的后缀数组后,再排序,排序后依次检测相邻的两个字符串的开头部分。

#include <iostream>
#include <cstring>
#include <stdio.h>
#include <algorithm>
using namespace std;
#define MAXLEN 10000
char str[MAXLEN], *arr[MAXLEN];

int CalLen(const char *str1, const char *str2)
{
    int len = 0;
    while(*str1 && (*str1++ == *str2++))
        len++;
    return len;
}

int pStrCmp(const void *str1, const void *str2)
{
    return strcmp(*(const char **)str1, *(const char **)str2);
}

int main()
{
    char ch;
    int n = 0;
    int maxlen = 0, maxIndex = 0;
    int temp;
    while((ch = getchar()) != '
')
    {
        arr[n] = &str[n];
        str[n++] = ch;
    }
    str[n] = '';
    qsort(arr, n, sizeof(char *), pStrCmp);
    for(int i = 0; i < n - 1; i++)
    {
        temp = CalLen(arr[i], arr[i + 1]);
        if(temp > maxlen)
        {
            maxlen = temp;
            maxIndex = i;
        }
    }
    cout << arr[maxIndex] << endl;;
}
原文地址:https://www.cnblogs.com/awy-blog/p/3991838.html