求一個字符串中連續出現次數最多的子串
阿新 • • 發佈:2017-06-11
article 規律 生成 clu 一次 strong tor first sub
題目:求一個字符串中連續出現的次數最多的子串。
例如,字符串“abababc”,最多連續出現的為ab,連續出現三次。
思路:
例如字符串“abababc”,最多連續出現的為ab,連續出現三次。要和求一個字符串中的最長重復子串區分開來,還是上面的字符串,那麽最長的重復子串為abab。
兩個題目的解法有些類似,都用到了後綴數組這個數據結構。求一個字符串中連續出現的次數最多的子串,首先生成後綴數組例如上面的字符串為:
abababc
bababc
ababc
babc
abc
bc
c
可以看出第1個後綴數組和第3個後綴數組的起始都為ab,第5個後綴數組也為ab。
可以看出規律來,一個字符串s,如果第一次出現在後綴數組i的前面,那麽如果它重復出現,下一次出現應該在第i+len(s)個後綴數組的前面。
下面是代碼:
#include <iostream> #include <cstring> #include <utility> #include <string> #include <vector> using namespace std; pair<int, string> fun(const string& str) { vector<string> subs; int len = str.size(); for (int i = 0; i < len; i++) { subs.push_back(str.substr(i)); } int count = 1; int maxCount = 1; string sub; for (int i = 0; i < len; i++) { for (int j = i + 1; j < len; j++) { count = 1; if (subs[i].substr(0, j - i) == subs[j].substr(0, j - i)) { ++count; //j-i為子串長度 for (int k = j + j - i; k < len; k += j - i) { if (subs[i].substr(0, j - i) == subs[k].substr(0, j - i)) { ++count; } else { break; } } if (count > maxCount) { maxCount = count; sub = subs[i].substr(0, j - i); } } } } return make_pair(maxCount, sub); } int main() { string str; pair<int, string> rs; while (cin>>str) { rs = fun(str); cout<<rs.second<<":"<<rs.first<<endl; } return 0; }
另一種思路:
pair<int, string> fun(const string& str) { vector<string> subs; int len = str.size(); for (int i = 0; i < len; i++) { subs.push_back(str.substr(i)); } int count = 1; int maxCount = 1; string sub; //i為子串的長度 for (int i = 1; i < len; i++) { for (int j = 0; j + i < len; j += 1) { int k = j; count = 1; while (k + i < len && subs[k].substr(0, i) == subs[k + i].substr(0, i)) { ++count; k += i; } if (count > maxCount) { maxCount = count; sub = subs[j].substr(0, i); } } } return make_pair(maxCount, sub); }
參考:http://blog.csdn.net/foreverling/article/details/46883515
求一個字符串中連續出現次數最多的子串