最长公共子序列/子串 LCS(模板)
2024-08-31 13:50:35
首先区分子序列和子串,序列不要求连续性(连续和不连续都可以),但子串一定是连续的
1.最长公共子序列
1、最长公共子序列问题有最优子结构,这个问题可以分解称为更小的问题
2、同时,子问题的解释可以被重复使用的,也就是说更高级别的子问题会重用更小子问题的解。
满足这两点以后,很容易就想到用动态规划来求解。
1.假设两个字符串s1, s2。当其中一个串的长度为0时,公共子序列的长度肯定为0。
2.假设s1的第i个字符与s2的第j个字符相等时,最长子序列等于s1的第i-1个字符与s2的第j-1个字符最长子序列长度+1。
3.假设s1的第i个字符与s2的第j个字符不相等时,最长子序列等于s1的第i个字符与s2的第j-1个字符最长子序列长度或s1的第i-1个字符与s2的第j个字符最
长子序列长度中最大那一个。
dp[i][j]表示s1的第i个字符与s2的第j-1个字符最长子序列长度
#include<iostream>
#include<math.h>
#include<string.h>
using namespace std;
int dp[][];
int len1,len2;
void lcs(string s1,string s2)
{
for(int i=;i<=len1;i++)//初始化
dp[i][]=;
for(int i=;i<=len2;i++)
dp[][i]=;
for(int i=;i<=len1;i++)
{
for(int j=;j<=len2;j++)
{
if(s1[i-]==s2[j-])
dp[i][j]=dp[i-][j-]+;
else
dp[i][j]=max(dp[i-][j],dp[i][j-]);
}
} }
void Print(string s1,string s2)//输出公共子序列
{
string str="";
while(len1>=&&len2>=)//从字符串s1,s2的末尾位置往前推
{
if(s1[len1-]==s2[len2-])
{
str=str+s1[len1-];
len1--;
len2--;
}
else
{
if(dp[len1][len2-]>dp[len1-][len2])//说明公共的字符在字符串s1的i位置之前,与字符s2[j]无关
len2--;
else
len1--;
}
}
for(int i=str.length();i>=;i--)
cout<<str[i]<<' ';
cout<<endl;
}
int main()
{
string s1,s2;
cin>>s1>>s2;
len1=s1.length();
len2=s2.length();
lcs(s1,s2);
cout<<dp[len1][len2]<<endl;
Print(s1,s2);
return ;
} // aaeefdhe
// saabcd //3
// a a d
2.最长公共子串
最长公共子串跟最长公共子序列的唯一区别在于,公共子串要求是连续的,子序列要求不一定连续。
具体的思路还是动态规划,不同点在于动态规划的迭代策略
#include<iostream>
#include<math.h>
#include<string.h>
using namespace std;
int dp[][];
int len1,len2;
int mx_len=,End=;//End是公共字串结束的位置
void lcs(string s1,string s2)
{
for(int i=;i<=len1;i++)//初始化
dp[i][]=;
for(int i=;i<=len2;i++)
dp[][i]=;
for(int i=;i<=len1;i++)
{
for(int j=;j<=len2;j++)
{
if(s1[i-]==s2[j-])
dp[i][j]=dp[i-][j-]+;
else
dp[i][j]=; if(dp[i][j]>mx_len)
{
mx_len=dp[i][j];
End=i-;
}
}
} } int main()
{
string s1,s2;
cin>>s1>>s2;
len1=s1.length();
len2=s2.length();
lcs(s1,s2);
cout<<mx_len<<endl;
for(int i=End-mx_len+;i<=End;i++)
cout<<s1[i];
cout<<endl;
return ;
} // aaeefdhe
// saabcd //2
//aa
最新文章
- Visual Studio 2015 和 Apache Cordova 跨平台开发入门(一)
- BZOJ 1503: [NOI2004]郁闷的出纳员
- 粗略了解struts2
- UNITY3d在移动设备上的一些优化实战(一)-概述
- ajax异步提交文件
- chrome下float元素下input选中内容bug
- [Bhatia.Matrix Analysis.Solutions to Exercises and Problems]ExI.3.6
- TDD三大定律
- ASPNET程序中常用的三十三种代码
- tree btn
- android:onTouch()和onTouchEvent()的区别?看完这篇文章就知道了
- 1.搜索引擎的历史,搜索引擎起步,发展,繁荣,搜索引擎的原理,搜索技术用途,信息检索过程,倒排索引,什么是Lucene,Lucene快速入门
- centos 安装 vsftpd
- [Swift]LeetCode326. 3的幂 | Power of Three
- Redis学习笔记(1)-安装Oracle VM VirtualBox
- February 15th, 2018 Week 7th Thursday
- MySQL分页时统计总记录行数并使用limit返回固定数目的记录
- JavaScript权威指南--脚本化HTTP
- NAT alg 和 ASPF
- Spring MVC中如何解决POST请求中文乱码问题,GET的又如何处理呢