最长公共子串
来源:互联网 发布:经纬度换算器软件 编辑:程序博客网 时间:2024/06/04 04:04
最长公共子串问题与最长公共子序列不同,最长公共子串要求公共序列是连续分布在母串中,比如s1 = "abcdef" ,s2 = "acdebf", 则s1与s2的最长公共子序列长度为5,公共子序列为 "acdef",最长公共子串长度为3,公共串为 "cde"; 最长公共子序列可以用dp做,同样最长公共子串也可以用dp做。
考虑两序列 A="GCGCAATG" , B="GCCCTAGCG",先构造(A[i], B[j]) 大小为m*n的矩阵C,其中m=length(A), n=length(B);A[i] == B[j]等价于C[i][j]=1; 否则C[i][j]为0;因为是求最长公共串长度,不妨对C做下变形,
即若有A[i] == B[j] ,则令C[i][j] = C[i-1][j-1] + 1,否则C[i][j]=0; 初始条件 C[0][j] ==(A[0]==B[j]?1:0);则可以构造出矩阵C
————图片来自 http://www.cnblogs.com/zhangchaoyang/articles/2012070.html
容易知道,矩阵C的最大元素值即为最长公共子串的长度。我们可以再构造矩阵的过程中保存当前得到的最长公共子串的末尾字符及长度。
分析下复杂度,时间复杂度就是构造矩阵过程为O(m*n),空间复杂度O(m*n);
空间还可以优化,因为我们是一行一行的构造,当前行的值仅依赖于上一行的值,因此可以用一滚动数组来代替二维矩阵,下面是C++的实现,程序中的两个序列不是字符串,而是数组,对于其他类型的序列只要稍微改下即可完全套入
pair<int,int> LCS(vector<int> &A,vector<int> &B){int m = A.size(), n = B.size();pair<int,int> res = make_pair(-1,0);int *comn = new int[n];fill_n(comn,n,0);//构造(A[i],B[j])的矩阵C,如果A[i]==B[j]则点C[i][j]=1,否则C[i][j]=0//lcs[i][j]表示C[i][j]所在的左上对角线上C[i][j]前连续1的长度//为节省空间用滚动数组for(int i=0;i<m;i++){ for(int j=n-1;j>=1;j--){ comn[j] = 0; //lcs[i][j]=lcs[i-1][j-1] + (A[i]==B[j])if(A[i]==B[j]){comn[j]=comn[j-1]+1;if(res.second<comn[j]){ res.first = A[i]; res.second=comn[j];}}//cout<<"test:"<<comn[j]<<" ";}comn[0] = (A[i]==B[0]?1:0);// cout<<"test:"<<comn[0]<<endl;if(res.second<comn[0]){ res.first = A[i]; res.second=1;}}return res;}
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 如何在Ubuntu 14.04中创建SWAP交换分区文件
- 统计你的代码数
- StringBuffer和string的传化
- iPhone 6/6 Plus 出现后,如何改进工作流以实现一份设计稿支持多个尺寸?
- 什么是GOP
- 最长公共子串
- Surrounded Regions结题报告
- AS6 配置telnet和ftp
- Set接口之HashSet、TreeSet、EnumSet
- 如何在eclipse中设置@author为自己的名字
- Android Studio导入第三方类库的方法
- iOS 两种方式实现瀑布流效果剑客篇(欢迎提建议和分享经验)
- 计算2个复数的和、差、积、商(解决)
- DPM 检测源码分析