首页 > 试题广场 >

手写代码:两个字符串的最长公共子序列?

[问答题]

手写代码:两个字符串的最长公共子序列?

/*
解题思路:设置一个二维数组dp[][],令dp[i][j]表示以s1[i]作为末尾和以s2[j]作为末尾的最长公共子序列的长度因此,通过设置这么一个二维数组,最长公共子序列的长度便是数组dp[n][m]的值。dp[i][j]表示以s1[i]作为末尾和以s2[j]作为末尾的最长公共子序列的长度,根据s1[i]和s2[j]的关系可以分为两种情况:
1)s1[i]=s2[j],即s1中的第i个字符和s2中的第j个字符相同,此时必定存在一个最长公共子串s1[i]和s2[j]结尾,其他部分等价于s1中前i-1个字符和s2中前j-1个字符的最长公共子串,于是这个子串的长度比dp[i-1][j-1]多1,即dp[i][j]=dp[i-1][j-1]+1.
2)s1[i]!=s2[j],此时最长公共子串长度为s1中前i-1个字符和s2中前j个字符的最长公共子串长度与s1中前i个字符和s2中前j-1个字符的最长公共子串长度的较大者,即在这两种情况下得到的最长公共子串都不会因为其中一个字符串又增加了一个字符长度而发生变化也就是dp[i[j]=max(dp[i-1][j],dp[i][j-1]).
从这两种情况可以得到状态转移方程:
dp[i][j] = dp[i-1][j-1]+1       s1[i]=s2[j]
dp[i][j] = max(dp[i-1][j],dp[i][j-1]) s1[i]!=s2[j]
边界情况:
dp[i][0] = 0 (0<=i<=n)
dp[0][j] = 0 (0<=j<=n)
*/
#include <iostream>
#
include <cstring>
using namespace std;
char sz1[1000];
char sz2[1000];
int dp[1000][1000];
int main(){
while(cin >> sz1 >> sz2 ){

int length1 = strlen(sz1);
int length2 = strlen(sz2);
int i, j;
for(i = 0; i <= length1; i++){
dp[i][0] = 0;
}
for(j = 0; j <= length2; j++){
dp[0][j] = 0;
}

for(i = 1; i <= length1; i++){
for(j = 1; j <= length2; j++){
if(sz1[i-1] == sz2[j-1]){
dp[i][j] = dp[i-1][j-1] + 1;
}
else{
dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
}
}
}
cout << dp[length1][length2] << endl;
}
return 0;
}
编辑于 2020-03-04 13:48:43 回复(0)