時間:2014.09.12
地點:基地
心情:明天就要和歐陽去武漢面試阿里了,整理一下同學求助的一道題,寫下這一篇,願一切順利。
一、題目:
求一個字符串中連續出現最多的子串次數:例如字符串abcbcbcabc,連續出現次數最多的子串是bc,出現次數爲3。
二、分析
方法:後綴思路
比如題目中舉例中的字符串,它的後綴有:
abcbcbcabc 0
bcbcbcabc 1
cbcbcabc 2
bcbcabc 3
cbcabc 4
bcabc 5
cabc 6
abc 7
bc 8
c 9
容易看出,所求的那段字串bc等間隔性的出現在不同一系列後綴中,於是可從源字符串中取兩個端點間的字串並規律性地和後綴中等距離的字串前綴比較,若是發生匹配則計數器加1,若是不匹配放continue進入下一輪。
舉例來說:1.先從源串中即0號後綴中取出a,因爲只取出一個字符,所以若重現,則緊接着的1號後綴首字符也應該是,與之比較,a!=b,計數器保持爲1,接着取ab,現在有兩個字符,若重複,則在2號後綴前兩個字符應該匹配,ab!=cb,匹配失敗,計數器保持爲1...如此重複,當右端點其實到達源串中點位置時即可打止,避免之後不必要的計算了。當取bc時,會和3號5號後綴前兩字符發生匹配,計數器相應加1,且更新最大值,等等,最後得出結論:
三、代碼
size_t GetMaxRepeatSubLen(const string& str)
{
size_t max_len = 1;
size_t str_len = str.length();
for (size_t i = 0; i < str_len; ++i)
{
for (size_t j = i + 1; j < str_len/2; ++j)
{
string pattern = str.substr(i, j - i);
if (pattern == str.substr(j, j - i))
{
size_t offset = j - i;
int count = 2;
for (size_t k = j + offset; k < str_len; k += offset)
{
if (pattern == str.substr(k, offset))
count += 1;
else
break;
if (count>max_len)
max_len = count;
}
}
}
}
return max_len;
}