最长公共子串(LCS)(连续与非连续)
2014-11-14 15:29
302 查看
连续子串
1.思路
使用count[i][j]来表示s1[0......i-1]和s2[0......j-1]的最长公共子串。(即,c[1][1]表示s1的第一个字符构成的字符串与s2的第一个字符,特殊的,c[0][x]表示不包含s1字符的字符串和s2部分字符串公共字串,显然是0)。
因为子串必须是连续的,所以对于s1[i]和y[j]而言,他们要么和之前的公共子串构成新的公共子串,要么就不能构成公共子串。所以,如果不能构成公共子串,count[i][j]为0,否则,为之前公共子串长度+1。所以,状态转移方程为:
1) s1[i] == s2[j] count[i][j] = count[i-1][j-1] +1
2)s1[i] != s2[j] count[i][j] = 0
初始化时,对于i=0或j=0,表示不含字符,count[i][j] = 0
2.代码
= i-max;end = i-1;}}elsecount[i][j] = 0;}}System.out.println(max);System.out.println(s1.substring(begin, end+1));
非连续子串
1.思路
方法同上,状态转移方程为
1) s1[i] == s2[j] count[i][j] = count[i-1][j-1] +1
2)s1[i] != s2[j] count[i][j] = max{count[i-1][j],count[i][j-1]}
初始化时,对于i=0或j=0,表示不含字符,count[i][j] = 0
2.代码:
1.思路
使用count[i][j]来表示s1[0......i-1]和s2[0......j-1]的最长公共子串。(即,c[1][1]表示s1的第一个字符构成的字符串与s2的第一个字符,特殊的,c[0][x]表示不包含s1字符的字符串和s2部分字符串公共字串,显然是0)。
因为子串必须是连续的,所以对于s1[i]和y[j]而言,他们要么和之前的公共子串构成新的公共子串,要么就不能构成公共子串。所以,如果不能构成公共子串,count[i][j]为0,否则,为之前公共子串长度+1。所以,状态转移方程为:
1) s1[i] == s2[j] count[i][j] = count[i-1][j-1] +1
2)s1[i] != s2[j] count[i][j] = 0
初始化时,对于i=0或j=0,表示不含字符,count[i][j] = 0
2.代码
<pre name="code" class="java"> Scanner cin = new Scanner(System.in); String s1 = cin.next(); String s2 = cin.next(); <span style="white-space:pre"> </span>//因为0表示的是没有字符,所以必须到length+1才能包含字符串中所有字符 int[][] count = new int[s1.length()+1][s2.length()+1]; int max = 0; int begin=0,end=0;//用来记录最长公共子串的开始和结束位置 for(int i=0; i<=s1.length(); i++) { for(int j=0; j<=s2.length(); j++) {<pre name="code" class="java"><span style="white-space:pre"> </span>//因为0为不包含任何字符,所以所有下标为0的count均为0if(i==0 || j==0)count[i][j] = 0;}}//因为从1才表示是第一个字符for(int i=1; i<=s1.length(); i++){for(int j=1; j<=s2.length(); j++){
<span style="white-space:pre"> </span>//第i个字符在s1中下标为i-1if(s1.charAt(i-1) == s2.charAt(j-1)){count[i][j] = count[i-1][j-1]+1;if(max<count[i][j]){max = count[i][j];begin
= i-max;end = i-1;}}elsecount[i][j] = 0;}}System.out.println(max);System.out.println(s1.substring(begin, end+1));
非连续子串
1.思路
方法同上,状态转移方程为
1) s1[i] == s2[j] count[i][j] = count[i-1][j-1] +1
2)s1[i] != s2[j] count[i][j] = max{count[i-1][j],count[i][j-1]}
初始化时,对于i=0或j=0,表示不含字符,count[i][j] = 0
2.代码:
int[] a = {0, 1, 2, 3, 5}; int[] b = {1, 3, 5, 7, 9}; int[][] count = new int[a.length+1][b.length+1]; int max = -1; for(int i=0; i<a.length; i++) { for(int j=0; j<b.length; j++) { if(i==0 || j==0) count[i][j] = 0; } } for(int i=1; i<=a.length; i++) { for(int j=1; j<=b.length; j++) { if(a[i-1]==b[j-1]) count[i][j] = count[i-1][j-1]+1; else count[i][j] = Math.max(count[i][j-1], count[i-1][j]); if(max<count[i][j]) max = count[i][j]; } } System.out.println(max);
相关文章推荐
- LCS(最长公共子序列)注意:是可以不连续的,区别于最长公共子串
- 最长公共子序列(LCS)和最长公共连续子串
- 动态规划 最长公共子序列LCS、最长公共连续子串、最长重复子串
- LCS 最长公共子串算法实现 C#
- 20. 最长公共子串(ToDo)[LCS]
- 最长公共子串(LCS)
- 两个字符串的最长公共子串(子串为连续的)
- UVa 10192 - Vacation & UVa 10066 The Twin Towers ( LCS 最长公共子串)
- 最长公共子串(连续)
- LCS(最长公共子序列) GST(最长公共子串,广义后缀树)
- spoj1811 Longest Common Substring(LCS)最长公共子串
- SPOJ - LCS2 Longest Common Substring II 多个串的最长公共子串
- LCS/最长公共子串算法分析
- 求两个字符串的最长公共子串(LCS)
- 最长公共子串(LCS)
- 最长公共子序列LCS 与最长公共子串 两个问题的动态规化 解法
- 求最长连续公共子串
- LCS的java算法---考虑可能有多个相同的最长公共子串
- 美团2017编程题—拼凑钱币&大富翁游戏&最大矩形面积&最长公共连续子串
- spoj1811 Longest Common Substring(LCS)最长公共子串