动态规划—最长公共子序列和最长公共子串
最长公共子串是在两个String中找出最长的公共部分,子串为连续;
最长公共子序列是在两个string中找出最长的相同序列,子序列可以不连续;
最长公共子序列 例题:
给定两个字符串A和B,同时给定两个串的长度n和m,请返回最长公共子序列的长度。保证两串长度均小于等于300。
测试样例:
"1A2C3D4B56",10,"B1D23CA45B6A",12
返回:6
解题思路:用二维数组c[i][j]来表示字符串A中以(i-1)(以i-1这个位置)结尾,字符串B中以(j-1)结尾的子序列长度;
那么,
1.当A[i-1]==B[j-1]时,c[i][j]=c[i-1][j-1]+1;也就是当前A和B指向的字符相等,那么在位置i-1和位置j-1处的子序列长度在前一个的基础上加1;
2.当A[i-1]!=B[j-1]时,c[i][j]=max{c[i-1][j],c[i][j-1]},也就是当前A和B指向的字符不相等,那么在位置i和位置j除的子序列长度应该等于c[i-1][j]和
c[i][j-1]中的较大者。
最长公共子串 例题:
给定两个字符串A和B,同时给定两串的长度n和m。
测试样例:
"1AB2345CD",9,"12345EF",7
返回:4
最大公共子串的思路与上述思路一致,只是当A[i-1]!=B[j-1]时,c[i][j]=0。
最长公共子序列代码示例:
class
LCS {
public
:
int
findLCS(string A,
int
n, string B,
int
m) {
int
table[n + 1][m + 1];
for
(
int
i = 0;i <= n;++i)table[i][0] = 0;//初始化矩阵的第0列
for
(
int
i = 0;i <= m;++i)table[0][i] = 0;//初始化矩阵的第0行
for
(
int
i = 1;i <= n;++i){
for
(
int
j = 1;j < =m;++j){
if
(A[i-1] == B[j-1])
table[i ][j] = table[i - 1][j - 1] + 1;
else
{
table[i][j ] = max(table[i][j - 1],table[i - 1][j]);//等于较大值
}
}
}
return
table[n][m];
}
};
最长公共子串代码示例:
class
LongestSubstring {
public
:
int
findLongest(string A,
int
n, string B,
int
m) {
int c[n+1][m+1];
int
maxlen = 0;
for
(
int
i = 0;i <= n;++i) c[i][0] = 0;//初始化矩阵的第0列
for
(
int
i = 0;i <= m;++i) c[0][i] = 0;//初始化矩阵的第0行
//dp
for
(
int
i = 1; i <=n; ++i){
for
(
int
j = 1; j <=m; ++j){
if
(A[i-1] != B[j-1]){
c[i][j]=0;
}
else
{
//common substring ends with A[i] and B[j]
c
[i][j] = c[i-1][j-1] + 1;
maxlen = maxlen > c[i][j] ? maxlen : c[i][j];
}
}
}
return
maxlen;
}
};
博主原创博文,未经允许,请勿转载!
尽管未来的路还很迷茫,不知从何开始,但我不会就此放弃!