最长公共子序列
来源:互联网 发布:2017年时代网络诗人奖 编辑:程序博客网 时间:2024/06/17 01:36
Description
本题需要用lcs算法来实现字符串匹配。
一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列。
输入有多行,每一行是一个测试用例,最后的结束标志为EOF标志
每个测试用例是由两个字符串组成的,中间用空格隔开(字符串本身不包含任何空白符)
两个字符串的长度len都满足:0 < len < 1000
Output
对于每一个测试用例,输出它的最长公共子序列的长度,每个输出占一行
Sample Input
ABCDEFG ABDHTK
ABCDEFG ABDHTKCD
Sample Output
3
4
题解:
通过本题来理清LCS算法的思路。
最长公共子串(Longest Common Substring)与最长公共子序列(Longest Common Subsequence)的区别: 子串要求在原字符串中是连续的,而子序列则只需保持相对顺序一致,并不要求连续。比如:对于ABAAC、ABDDC而言,他们的最长公共子串为AB,最长公共子序列为ABC。
(1)求解最长公共子串
对于求解最长公共子串而言,最初的算法必然是暴力求解,即采用嵌套循环遍历源字符串,并已所记录的最大子序列长度作为答案。
显示这样的效率不足以通过测评,我们再对题目进行分析。
假设源字符串A,B长度分别为n,m,构造一个大小为n*m的矩阵C,其中C[i] [j] = 1当且仅当A[i]==B[j],C[i] [j] = 0当且仅当A[i]!=B[j].
那么根据题意,显然最长公共子序列的长度为该矩阵中斜对角线方向上连续的1的最大长度。这样的效率也不高,除去嵌套循环以外还需要计算连续的1的最大长度,显然我们可以令C[i][j] =C[i-1][j-1]+1当且仅当A[i]==B[j],这样只需要记录矩阵中最大数字即可。
(2)求解最长公共子序列
假设源字符串A,B长度分别为n,m,构造一个大小为(n+1)(m+1)的矩阵C,其中C[0][] = 0,C[*][0] = 0.
通过动态规划思想可知,存在转移方程:
if (A[i]==B[j]) C[i][j] = C[i-1][j-1] +1;
else C[i][j] = MAX(C[i-1][j],C[i][j-1]);
显然,这样可以求解出最长公共子序列,但是遇到卡时间、空间的时候,我们需要对其进行优化。
在这道题中,我们采用滚动数组+动态规划来AC这道题。
Code:
// Problem#: 20998// Submission#: 5187697// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/// All Copyright reserved by Informatic Lab of Sun Yat-sen University#include <stdio.h>#include <memory.h>const int MAXN=1000+10;int dp[2][MAXN];char a[MAXN],b[MAXN];int main(){ while(~scanf("%s%s",a+1,b+1)){ int i = 1,j = 1,m=0; memset(dp,0,sizeof(dp)); for( i=1;a[i];i++){ m^=1; for(j=1;b[j];j++){ dp[m][j] = dp[m^1][j]; if (dp[m][j-1]>dp[m][j])dp[m][j]=dp[m][j-1]; if (a[i]==b[j]&&dp[m^1][j-1]+1>dp[m][j]) dp[m][j] = dp[m^1][j-1]+1; } } printf("%d\n",dp[m][j-1]); } return 0;}
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列...
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- css-垂直居中多种解决方式
- 卷积神经网络——输入层、卷积层、激活函数、池化层、全连接层
- JavaWeb 解决中文传参乱码
- pulltorefresh上拉下拉刷新的用法
- ubuntu64-server安装
- 最长公共子序列
- PTA 7-2 列车调度(25 分)
- Tensorflow 学习与复习 Epoch_1 # tensorflow的一些函数方法
- bzoj1560 [JSOI2009]火星藏宝图(dp+贪心)
- android 五大布局(1)线性布局
- 1到100之间质数的和--JAVA
- 第一二章课后习题
- 商城模式转换,recyclerView的LinearLayoutManager转成GridLayoutManager出现的bug
- 设计模式【迭代器模式Iterator Pattern】