最長不重複字串

編程:給定兩個字符串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;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章