1
我正在爲自己的實踐做這個問題,並不確定我是否以最有效的方式進行操作。請分享任何關於提高效率和算法的想法。3串輸入中最長的公共子串
我的算法:
- 爲每個相應的字符串3個後綴數組。
- 創建後綴數組:一個遍歷字符串的循環,然後使用stl庫對向量排序,所以我相信這個字符串的預處理是O(n * nlogn)。 (我應該如何降低這裏的複雜度?)
- 然後遍歷任何向量並比較所有三個輸入字符串的後綴字符串,並與您所擁有的最大值進行比較。
代碼:
string commonLongestSubstring(string str1, string str2, string str3)
{
int length1 = str1.length(), length2 = str2.length(), length3 = str3.length();
if (length1 == 0 || length2 == 0 || length3 == 0)
return "";
vector<string> suffixArray1 = getSuffixArray(str1);
vector<string> suffixArray2 = getSuffixArray(str2);
vector<string> suffixArray3 = getSuffixArray(str3);
string longestCommon = "";
for (int i = 0; i < suffixArray1.size() && i < suffixArray2.size() && i < suffixArray3.size(); ++i) {
string prefix = commonPrefix(suffixArray1[i], suffixArray2[i], suffixArray3[i]);
if (longestCommon.length() < prefix.length())
longestCommon = prefix;
}
return longestCommon;
}
string commonPrefix(string a, string b, string c)
{
string prefix;
for (int i = 0; i < a.length() && i < b.length() && i < c.length(); ++i) {
if (a[i] != b[i] || a[i] != c[i])
break;
prefix = prefix + a[i];
}
return prefix;
}
vector<string> getSuffixArray(string str)
{
int length = str.length();
vector<string> suffixesContainer;
for (int i = 0; i < length; ++i) {
suffixesContainer.push_back(str.substr(i, length));
}
sort(suffixesContainer.begin(), suffixesContainer.end());
return suffixesContainer;
}
疑惑:
- 如何減少在那裏我預處理suffixArray部分的複雜性?
- 這是三個字符串,但如果問題的大小增加到n-string,那麼這個算法將不起作用,因爲那樣我就要創建n-suffixArrays。那麼我們通常如何處理這種情況呢?
- 關於我們通常如何解決這類問題(子字符串)的一般想法?
(語言沒有障礙)
它看起來像有一個專門的維基百科頁面(使用算法部分和僞代碼 - 這應該有助於複雜性部分):http://en.wikipedia.org/wiki/Longest_common_substring_problem – nha