問題描述:
給定一個字符串,如abcdaaabbbaaaabcdbbb,這個串中最長重複子串爲abcd;若有多個長度相等的重複子串,只需輸入第一個最長的。
最直觀的算法設計:
設給定的字符串爲s=“a1a2a3...an”,則對任意ai,在i+1到n之間查找aj, s.t. ai=aj,用idx記下此時ai下標,即i;然後依次比較ai+1,ai+2...與aj+1, aj+2是否相同,並記下最長相等的串的長度len,若此長度大於歷史最大長度,則用idx及len更新歷史最優值。重複此過程,直至i>=s.length()。算法複雜度爲O(n^2),應該還有改進空間吧,大家可以寫下自己的思路,一起討論。
基於以上算法,可以很容易寫出C++版代碼:
#include <iostream>
#include <cstring>
using namespace std;
void printMaxDuplication(const char* src){
if(!src){
return;
}
int len = strlen(src);
//記錄最長重複子串的起始位置以及對應最長的長度
int idx=0, maxLen=0;
for(int i =0; i < len; ++i){
for(int j = i+1, tempLen=0; j < len; ){
if(src[i] == src[j]){
//依次比較ai+1與aj+1。ai+2與aj+2
for(; src[j+tempLen] !='\0' && src[i+tempLen]==src[j+tempLen]; ++tempLen);
if(tempLen > maxLen){
maxLen = tempLen;
idx = i;
}
j += tempLen;
}else{
++j;
}
}
}
//print
for(int i =0; i < maxLen; ++i){
cout<<src[idx+i];
}
}
int main(){
char src[] = "aaacdefgaaaddedefg";
printMaxDuplication(src);
return 0;
}