最長重複子串問題

  今天面試被一道沒見過的題,徹底整悶了。求一段字符串的最長重複子串。後來網上看看博客,居然能夠用KMP寫,爲本身的無知感到羞愧。好吧,我來學習一下如何用KMP方法解決這樣的問題,關鍵是next的特性來解決這個問題。ios

#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()) != '\n')
    {
        arr[n] = &str[n];
        str[n++] = ch;
    }
    str[n] = '\0';
    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;;
}
相關文章
相關標籤/搜索