LCS模板,求长度,并记录子串

 1 //LCS模板,求长度,并记录子串 
 2 //亦可使用注释掉的那些代码,但所用空间会变大
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<cstdlib>
 7 #include<cstdio>
 8 using namespace std;
 9 #define N 5005
10
11 int len[N][N];
12 char str1[N],str2[N],str3[N];
13 int k;
14
15 int lcsLen(char *s1,int n1,char *s2,int n2)//求长度
16 {
17     for(int i=0;i<=n1;i++)
18     len[i][0]=0;
19     for(int j=0;j<=n2;j++)
20     len[0][j]=0;
21     for(int i=1;i<=n1;i++)
22     {
23         for(int j=1;j<=n2;j++)
24         {
25             if(s1[i-1]==s2[j-1])
26             len[i][j]=len[i-1][j-1]+1;
27             else
28             len[i][j]=max(len[i-1][j],len[i][j-1]);
29         }
30     }
31     return len[n1][n2];
32 }
33
34 void LCS(char *s1,char *s2,int i,int j)//递归求字串,存在tr3中
35 {
36     if(i==0||j==0)
37     return ;
38     if(s1[i-1]==s2[j-1])
39     {
40         LCS(s1,s2,i-1,j-1);
41         str3[k++]=s1[i-1];
42     }
43     else if(len[i-1][j]>=len[i][j-1])
44     LCS(s1,s2,i-1,j);
45     else
46     LCS(s1,s2,i,j-1);
47 }
48
49 void lcs(char *s1,int n1,char *s2,int n2)//求字串
50 {
51     memset(str3,0,sizeof(str3));
52     lcsLen(s1,n1,s2,n2);
53     k=0;
54     LCS(s1,s2,n1,n2);
55 }
56 int main()
57 {
58     int n1,n2;
59     while(cin >> str1 >> str2)
60     {
61         n1=strlen(str1);
62         n2=strlen(str2);
63         lcs(str1,n1,str2,n2);
64         cout << str3 << endl;
65         cout << lcsLen(str1,n1,str2,n2) << endl;
66     }
67     return 0;
68 }
时间: 2024-10-16 00:26:32

LCS模板,求长度,并记录子串的相关文章

POJ - 3415 Common Substrings(后缀数组求长度不小于 k 的公共子串的个数+单调栈优化)

Description A substring of a string T is defined as: T( i, k)= TiTi+1... Ti+k-1, 1≤ i≤ i+k-1≤| T|. Given two strings A, B and one integer K, we define S, a set of triples (i, j, k): S = {( i, j, k) | k≥ K, A( i, k)= B( j, k)}. You are to give the val

POJ 3415 Common Substrings (求长度不小于k的公共子串的个数)

Common Substrings Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 10002   Accepted: 3302 Description A substring of a string T is defined as: T(i, k)=TiTi+1...Ti+k-1, 1≤i≤i+k-1≤|T|. Given two strings A, B and one integer K, we define S,

POJ 2774 后缀数组:求最长公共子串

思路:其实很简单,就是两个字符串连接起来,中间用个特殊字符隔开,然后用后缀数组求最长公共前缀,然后不同在两个串中,并且最长的就是最长公共子串了. 注意的是:用第一个字符串来判断是不是在同一个字符中,刚开始用了第二个字符的长度来判断WA了2发才发现. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #include<

hdu1159 LCS模板题

题目分析 原题地址 最简单的最长公共子序列(LCS)问题的模板题了.不解释. ------------------------------------------------------------------------ 状态转移方程: dp[i][j]=dp[i-1][j-1]+1                                 (a[i-1]==b[j-1]) dp[i][j]=max(dp[i-1][j],dp[i][j-1] )              (a[i-1]

求最长升序子串的算法

今天复习了一下以前自己写的求最长升序子串的c语言代码,竟然发现有点不太懂,现在贴出来重新温习一下. 源代码贴出来如下: #include<stdio.h>#include<string.h>void main(){ char arry[10001]; int len,max=0,i,j,num[10001],k; gets(arry); len=strlen(arry); num[0]=1; for(i=0;i<len;i++) { k=0; for(j=0;j<i;j

poj 2774 Long Long Message,后缀数组,求最长公共子串 hdu1403

题意:给出两个字符串,求最长公共子串的长度. 题解:首先将两个字符串连在一起,并在中间加一个特殊字符(字串中不存在的)分割,然后两个串的最长公共字串就变成了所有后缀的最长公共前缀.这时就要用到height数组,因为任意两个后缀的公共前缀必定是某些height值中的最小值,而这个值如果最大则一定是height中的最大值.在此题中还要注意height最大一定要在两个值所代表的后缀分属不同的字符串地前提下. #include<cstdio> #include<cstring> #incl

【文文殿下】后缀自动机(SAM)求最长公共子串的方法

首先,在A 串上建立一个SAM,然后用B串在上面跑.具体跑的方法是: 从根节点开始,建立一个指针 p ,指着B串的开头,同步移动指针,沿着SAM的边移动,如果可以移动(即存在边)那么万事皆好,直接len++就好,但是,如果无法继续转移(失配了),那么,我们考虑跳回其父节点,因为其父节点的Right集是当前状态的真超集,那么其父节点状态所代表的字符串的集合中的任意一个字符串,都是当前状态所代表的字符串集合中的正在匹配的字符串(会不会一定是最长串?)的后缀,所以,有一个贪心的思想:父节点状态中的最长

HDU4622:Reincarnation(后缀数组,求区间内不同子串的个数)

Problem Description Now you are back,and have a task to do: Given you a string s consist of lower-case English letters only,denote f(s) as the number of distinct sub-string of s. And you have some query,each time you should calculate f(s[l...r]), s[l

顺序表 初始化 插入 删除 查找 合并 交换 判断为空 求长度

#include <stdio.h> #include <stdlib.h> #define OK 1 #define TRUE 1 #define ERROR -1 #define FALSE -1 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define LEN sizeof(SqList) #define MLC (Li