啊哈,演算法 之十 字尾陣列,求最長重複子串

2021-06-18 10:56:55 字數 2282 閱讀 1837

**:

直觀的解法是,首先檢測長度為 n - 1 的字串情況,如果不存在重複則檢測 n - 2, 一直遞減下去,直到 1 。

這種方法的時間複雜度是 o(n * n * n),其中包括三部分,長度緯度、根據長度檢測的字串數目、字串檢測。

利用字尾陣列

字尾陣列是一種資料結構,對乙個字串生成相應的字尾陣列後,然後再排序,排完序依次檢測相鄰的兩個字串的開頭公共部分。

這樣的時間複雜度為:生成字尾陣列 o(n),排序 o(nlogn*n) 最後面的 n 是因為字串比較也是 o(n)

依次檢測相鄰的兩個字串 o(n * n),總的時間複雜度是 o(n^2*logn),優於第一種方法的 o(n^3)

demo如下:

其中:當作為comlen函式引數的兩個字串長度相等時,該函式便返回這個長度值,從第乙個字元開始

int comlen( char *p, char *q )  

int main(void)

} }

......

......

......

return 0;

}

完整**如下:

#include using namespace std;  

#define maxchar 5000 //最長處理5000個字元

char c[maxchar], *a[maxchar];

int comlen( char *p, char *q )

int pstrcmp( const void *p1, const void *p2 )

int main(void)

c[n]='\0'; // 將陣列c中的最後乙個元素設為空字元,以終止所有字串

qsort( a, n, sizeof(char*), pstrcmp );

for(i = 0 ; i < n-1 ; ++i )

} printf("%.*s\n",maxlen, a[maxi]);

return 0;

}

元素a[0]指向整個字串,下乙個元素指向以第二個字元開始的陣列的字尾,等等。如若輸入字串為"banana",該陣列將表示這些字尾:

a[0]:banana

a[1]:anana

a[2]:nana

a[3]:ana

a[4]:na

a[5]:a

由於陣列a中的指標分別指向字串中的每個字尾,所以將陣列a命名為"字尾陣列"

對字尾陣列進行快速排序,以將字尾相近的(變位詞)子串集中在一起

qsort(a, n, sizeof(char*), pstrcmp)後

a[0]:a

a[1]:ana

a[2]:anana

a[3]:banana

a[4]:na

a[5]:nana

用comlen函式對陣列進行掃瞄比較鄰接元素,以找出最長重複的字串。

第二種方法是通過kmp演算法,next陣列的方式:

#includeusing namespace std;

const int max = 100000;

int next[max];

char str[max];

void getnext(char *t)

else

j = next[j];

} } int main(void)

} }

if(len > 0)

;int res = 0 , temp = 0;

char *out = output;

int final;

while(str[j] != '\0')

else

cnt[str[i]-'a']--;

i++;

} j++;

temp = j-i;

if(temp > res)

}//結果儲存在output裡面

for(i = 0 ; i < res ; ++i)

*out++ = str[final++];

*out = '\0';

return res;

}int main(void)

{ char a = "abcdefg";

char b[100];

int max = find(a,b);

cout<

字尾陣列求最長重複子串

於 問題描述 給定乙個字串,求出其最長重複子串 例如 abcdabcd 最長重複子串是 abcd,最長重複子串可以重疊 例如 abcdabcda,這時最長重複子串是 abcda,中間的 a 是被重疊的。直觀的解法是,首先檢測長度為 n 1 的字串情況,如果不存在重複則檢測 n 2,一直遞減下去,直到...

最長重複子串(字尾陣列)

時間限制 1000 ms 記憶體限制 3000 kb 描述 對於乙個字串s1,其中s2是他的乙個子串 長度嚴格小於s1長度 如果s2在s1 現次數超過1次,那麼s2就是乙個重複子串,現在的要求是給定s1,請求出他的最長重複子串 如果有多個長度一樣的最長子串,請輸入字典序最小那個串 比如bbbaaac...

最長重複子串 可重複 字尾陣列

時間限制 1000 ms 記憶體限制 3000 kb 描述 對於乙個字串s1,其中s2是他的乙個子串 長度嚴格小於s1長度 如果s2在s1中出現次數超過1次,那麼s2就是乙個重複子串,現在的要求是給定s1,請求出他的最長重複子串 如果有多個長度一樣的最長子串,請輸入字典序最小那個串 比如bbbaaa...