最长公共子序列

最长公共子序列(LCS)

て烟熏妆下的殇ゞ 提交于 2020-01-15 20:51:25
一,字串连续情况 LCS问题就是求两个字符串最长公共子串的问题。解法就是用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为1,否则为0。然后求出对角线最长的1序列,其对应的位置就是最长匹配子串的位置。 下面是字符串21232523311324和字符串312123223445的匹配矩阵,前者为X方向的,后者为Y方向的。不难找到,红色部分是最长的匹配子串。通过查找位置我们得到最长的匹配子串为:21232 0 0 0 1 0 0 0 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 1 0 0 1 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 1 0 0 1 0 1 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

最长公共子序列

跟風遠走 提交于 2020-01-15 20:40:56
#include"iostream" #include"cstdio" #include"algorithm" #include"cstring" #define N 500 using namespace std; int lcs[N][N];//lcs[x][y]表示 串1的第一位的到x,串2的第一位到y的最长子序列; char s1[N],s2[N]; int main() { while(~scanf("%s",s1)) { scanf("%s",s2); //cout<<s1<<" "<<s2<<endl; int l1=strlen(s1),l2=strlen(s2); for(register int i=0;i<=l1;++i) { for(register int j=0;j<=l2;++j) { if(i==0||j==0) lcs[i][j]=0;//初始化因为当lcs[0][0] i=0,表示串1长度为0,当串1为0;不可能就有公共子序列(!!关键) //同样 j=0,表示j=0,那么同样公共子序列为0; else if(s1[i-1]==s2[j-1])//因为先++l,但是字符串从0开始所应该判断是否s1[i-1],s2[j-1] { //意思是判断是串1 i-1位,串2 j-1位是否相同 lcs[i][j]=lcs[i-1][j-1]+1;/

最长公共子序列

守給你的承諾、 提交于 2020-01-14 19:27:40
最长公共子序列 注:子序列是可以不连续的。 递推公式: \(dp[i+1][j+1]=\begin{cases}dp[i][j]+1&(s_{i+1}=t_{j+1})\\max(dp[i][j+1],dp[i+1][j])&(其 他)\end{cases}\) 代码: // Created by CAD on 2020/1/14. #include <bits/stdc++.h> using namespace std; const int maxn=1e3+5; int dp[maxn][maxn]; int main() { ios::sync_with_stdio(false); cin.tie(0); string s,t; cin>>s>>t; int slen=s.length(),tlen=t.length(); for(int i=0;i<slen;++i) for(int j=0;j<tlen;++j) if(s[i]==t[j]) dp[i+1][j+1]=dp[i][j]+1; else dp[i+1][j+1]=max(dp[i+1][j],dp[i][j+1]); cout<<dp[slen][tlen]<<endl; return 0; } 来源: https://www.cnblogs.com/CADCADCAD/p/12193482.html

最长公共子序列-LeetCode1143

巧了我就是萌 提交于 2019-12-16 02:30:38
题目: 给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列。 一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。 例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。两个字符串的「公共子序列」是这两个字符串所共同拥有的子序列。 若这两个字符串没有公共子序列,则返回 0。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/longest-common-subsequence 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 输入:text1 = “abcde”, text2 = “ace” 输出:3 解释:最长公共子序列是 “ace”,它的长度为 3。 暴力算法,常规思路 从样例输入输出入手,输入两个字符串:abcde/ace。 按照字符串角标走的话,从左往右,角标同时想有移动,遇到相同字符则最长公共子序列+1。 两个字符串角标分别是i,j,如果i=0,j=0,那么我们可以知道s1[0]=s2[0],这时公共最长子序列有了字母a,那么剩下需要判断的则是 bcde 和 ce的公共最长子序列。 让i,j同时+1明显是不行的。

最长公共子序列

流过昼夜 提交于 2019-12-12 05:10:33
来源:牛客网 2016校招真题在线编程 知识点:动态规划 思路:《算法设计技巧与分析(沙特版)》动态规划 import java . util . * ; public class LCS { public int findLCS ( String A , int n , String B , int m ) { // write code here int [ ] [ ] L = new int [ n + 1 ] [ m + 1 ] ; for ( int i = 0 ; i <= n ; i ++ ) { L [ i ] [ 0 ] = 0 ; } for ( int i = 0 ; i <= m ; i ++ ) { L [ 0 ] [ i ] = 0 ; } for ( int i = 1 ; i <= n ; i ++ ) { for ( int j = 1 ; j <= m ; j ++ ) { if ( A . charAt ( i - 1 ) == B . charAt ( j - 1 ) ) { L [ i ] [ j ] = L [ i - 1 ] [ j - 1 ] + 1 ; } else { L [ i ] [ j ] = Math . max ( L [ i - 1 ] [ j ] , L [ i ] [ j - 1 ] ) ; } } }

动态规划之最长公共子序列问题(LCS)

你离开我真会死。 提交于 2019-12-08 11:33:20
问题描述 输入: X = { x 1 , x 2 , … … , x m } //--> Y = { y 1 , y 2 , … … , y m } //--> 输出: Z=X和Y的最长公共子序列 说明: 如果: X = { A , B , C } , Y = { A , C , D } //--> ,则X和Y的最长公共子序列 Z = { A , C } //--> 结构分析 我们将一个序列如 X //--> 的前 i //--> 个元素定义: X i //--> ,则有 X i = { x 1 , x 2 , … … , x i } //--> 我们将 X Y //--> 的最长公共子序列记为 L C S X Y //--> 我们将 X //--> 的前 i //--> 个和 Y //--> 的前 j //--> 个元素的最长公共子序列记为 L C S X i Y j //--> 我们看一下如下的关系: 我们假设 L C S X m Y n = Z = { z 1 , … … , z k } //--> 我们就可以知道 L C S X m − 1 Y n − 1 //--> 和 L C S X m Y n //--> 之间的关系为: (1)当 X m = Y n //--> 时: L C S X m Y n = L C S X m − 1 Y n − 1 + < x m = y

【算法系列 四】 String

五迷三道 提交于 2019-12-06 21:42:47
1. 字符串循环左移( 九度OJ1362 ),要求时间复杂度O(N),空间复杂度O(1) 这是一道基本的题目,简单说来就是三次翻转 比如:abcdef 左移两位 cdefab 过程: ab 翻转 ba cdef 翻转 fedc 将上面两个翻转后的结果拼接 bafedc 再翻转cdefab得到结果 代码: import java.io.IOException; import java.util.Scanner; public class Main { public static void main(String[] args) throws IOException { Scanner cin = new Scanner(System.in); int N; String str; while (cin.hasNext()) { str = cin.next(); N = cin.nextInt(); N = N % str.length(); String a = str.substring(0, N); String b = str.substring(N); StringBuffer abuffer = new StringBuffer(a); StringBuffer bbuffer = new StringBuffer(b); StringBuffer areverse =

AcWing 272. 最长公共上升子序列

情到浓时终转凉″ 提交于 2019-12-06 03:53:55
#include<iostream> using namespace std ; const int N=3030; int n; int a[N]; int b[N]; int f[N][N]; //f[i][j] //表示所有由第一个序列的前i个字母,和第二个序列的前j个字母构成的, //且以b[j]结尾的公共上升子序列 int main() { scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%d",&a[i]); for(int i=1; i<=n; i++) scanf("%d",&b[i]); for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) { //不包含a[i]的公共上升子序列 f[i][j]=f[i-1][j]; //包含的 if(a[i]==b[j]) { f[i][j]=max(f[i][j],1); for(int k=1; k<j; k++) if(b[k]<b[j]) f[i][j]=max(f[i][j],f[i][k]+1); } } int res=0; for(int i=1; i<=n; i++) res=max(res,f[n][i]); printf("%d\n",res); return 0; } 来源: https://www.cnblogs

最长公共子序列

霸气de小男生 提交于 2019-12-05 17:28:48
O(n²) #include<iostream> #include<cmath> #include<algorithm> #include<cstdio> #include<vector> #include<queue> #include<string.h> #include<set> #include<map> using namespace std; const int maxn =1e6+10; char a[maxn]; char b[maxn]; int f[1006][1006]; int main() { int n,m; cin >> n >> m; cin >> a+1; cin >> b+1; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { f[i][j]=max(f[i-1][j],f[i][j-1]); if(a[i]==b[j]) f[i][j]=max(f[i-1][j-1]+1,f[i][j]); } } cout << f[n][m] << endl; return 0; } 来源: https://www.cnblogs.com/wjc2021/p/11937056.html

AcWing 897. 最长公共子序列

拜拜、爱过 提交于 2019-12-04 22:24:00
#include <iostream> #include <algorithm> using namespace std; const int N = 1010; int n, m; char a[N], b[N]; int f[N][N]; int main() { scanf("%d%d", &n, &m); scanf("%s%s", a + 1, b + 1); for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= m; j ++ ) { f[i][j] = max(f[i - 1][j], f[i][j - 1]);//看一下第i和第j个字母有没有出现 //i-1,j-1 是包含在上面两种情况中的 if (a[i] == b[j]) f[i][j] = max(f[i][j], f[i - 1][j - 1] + 1); } printf("%d\n", f[n][m]); return 0; } 来源: https://www.cnblogs.com/QingyuYYYYY/p/11886728.html