編程:給定兩個字符串A,B(只包含26個英文字母),輸出所有公共的最長子字符串(如果出現重複子串,則輸出多次)
輸入包括兩行,每行爲一個連續字符串(大小寫敏感)
輸出包括多行,每行爲掃描到的最長公共子串,按照該子串在字符串A(即第一行輸入字符串)中出現的先後次序輸出
abcxyzabcrst
opqrstabc
樣例輸出:
abc
abc
rst
動態規劃
假設兩個字符串分別爲s和t,s[i]
和t[j]
分別表示其第i
和第j
個字符(字符順序從0
開始),再令L[i,
j]
表示以s[i]
和s[j]
爲結尾的相同子串的最大長度。應該不難遞推出L[i,
j]
和L[i+1,j+1]
之間的關係,因爲兩者其實只差s[i+1]
和t[j+1]
這一對字符。若s[i+1]
和t[j+1]
不同,那麼L[i+1,
j+1]
自然應該是0
,因爲任何以它們爲結尾的子串都不可能完全相同;而如果s[i+1]
和t[j+1]
相同,那麼就只要在以s[i]
和t[j]
結尾的最長相同子串之後分別添上這兩個字符即可,這樣就可以讓長度增加一位。合併上述兩種情況,也就得到L[i+1,j+1]=(s[i]==t[j]?L[i,j]+1:0)
這樣的關係。
#include<iostream>
#include<vector>
using namespace std;
int main()
{
string str1 = "abcxyzabcrst";
string str2 = "opqrstabc";
int max = 0;
vector<vector<int>> c(str1.size() + 1, vector<int>(str2.size() + 1,0));
for (int i = 0; i < str1.size() + 1;i++)
for (int j = 0; j < str2.size() + 1; j++)
{
if (i == 0 || j == 0) c[i][j] = 0;
else if (str1[i - 1] == str2[j - 1])
{
c[i][j] = c[i - 1][j - 1]+1;
max=max>c[i][j] ? max : c[i][j];
}
else
{
c[i][j] = 0;
}
}
for (int i = 0; i < str1.size() + 1; i++)
for (int j = 0; j < str2.size() + 1; j++)
{
if (c[i][j] == max)
{
for (int k = max; k>0; --k)
{
cout << str1[i- k];
}
cout << endl;
}
}
return 0;
}