2023/2/6总结
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
今天学习了LCS,用动态规划解决最长公共子序列和最长公共子串。
LCS
LCS有俩种一个是最长公共子序列(Longest Common Sequence)另外一个是最长公共子串(Longest Common Substring)。
最长公共子序列
LCS最长公共子序列是指在俩个字符串当中公共的“序列”。我们通常要求的是长度。
比如
A串1238945999
B串123774519
则最长公共子序列为
A串1238945999
B串123774519
为123459长度为6序列是不一定连续连续的叫做最长公共子串。
如何实现?
DP动态规划
首先我们看上面这个
i代表A串的位置j代表B串的位置。
如果当前a[i]==b[j],说明当前位置有一个相同那么就是前面不取ij所得到的答案+1,也就是dp[i-1][j-1]+1
如果不相等那么我们就要考虑俩种情况了是不考虑当前a串i的位置dp[i][j-1]大还是当前不考虑b串j的位置(dp[i-1][j])大。
所以就变成了
代码如下
#include<stdio.h>
#define N 1000
char s1[N+3],s2[N+3];
char dp[N+5][N+5];
int max(int a,int b)
{
if(a>b) return a;
return b;
}
int main()
{
int i,j;
scanf("%s%s",s1+1,s2+1);
for(i=1;s1[i];i++)
{
for(j=1;s2[j];j++)
{
if(s1[i]==s2[j])
{
dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
}
else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
printf("%d",dp[i-1][j-1]);
}
最长公共子串
最长公共子串是找公共的子串也是运用到了DP。
这个和上面不同的就是字符要是连续的。
比如
A串1238945999
B串123454519
答案为3 是123
我们还是需要分情况讨论
如果当前B串i的位置和A串j的位置相等那么我们可以知道如果它为dp[i-1][j-1]+1
因为dp[i-1][j-1]要么不等于为0要么等于为另外一个数字。
如果不相等直接为0即可。
在这个过程中找最大值即可。
代码为
#include<stdio.h>
#define N 1000
char s1[N+3],s2[N+3];
char dp[N+5][N+5];
int m;
int max(int a,int b)
{
if(a>b) return a;
return b;
}
int main()
{
int i,j;
scanf("%s%s",s1+1,s2+1);
for(i=1;s1[i];i++)
{
for(j=1;s2[j];j++)
{
if(s1[i]==s2[j])
{
dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
}
else dp[i][j]=0;
if(m<dp[i][j]) m=dp[i][j];
}
}
printf("%d",m);
return 0;
}