时间复杂度为O(m*n)最长公共子串

来源:互联网 发布:淘宝试用成功要付费吗 编辑:程序博客网 时间:2024/05/17 22:20

什么叫最长公共子串,就是两个字符串当中最长的连续的公共子串,注意连续;而子序列可以不连续,顺序一样即可,不要混淆。

对于两个子串,我们先找出短字符串L中(长的也可以)每个字符在长字符串H中的位置,这样我们就构建出一个二维表:

L:deasdfe1ra

H:unnasdsdfew333




这样,我们只需要找到如图所示类似的矢量线就可以了,在构建这样的二维表时,是按行的循序构建的,每当查询到x==y时,就给此单元赋值:(x-1,y-1)+1

并同时记录下最大值MAX和其坐标;当表构建完时,只需要拿出最大值得坐标,依次右上遍历,就可以取得最长公共子串了;

这样算法的时间复杂度就为O(m*n);//两子串长度乘积

好吧,我把这件的Java代码实现放下面,如果有更好的实现方案,欢迎分享出来,谢谢:


package temp;import java.util.ArrayList;import java.util.HashSet;/** *  * @author SheyChen * */public class Temp {/** *  * @param l 短的字符串(长的也行) * @param h 长字符串 * @return 换回最长子串集合,考虑到有多个最大子串长度相等 */public static HashSet<String> foo(String l, String h) {char[] cl = l.toCharArray();char[] ch = h.toCharArray();int[][] arry = new int[cl.length][ch.length];int max = 0;/** * List中存放的Int数组长度为2,第一位子串在是cl中最后一位元素所占的下标,第二位是子串长度 */ArrayList<int[]> val = new ArrayList<int[]>();/** * 构建二维表 */for (int i = 0; i < cl.length; i++) {for (int j = 0; j < ch.length; j++) {if (cl[i] == ch[j]) {if (i == 0 || j == 0)arry[i][j] = 1;elsearry[i][j] = arry[i - 1][j - 1] + 1;if (arry[i][j] == max) {int[] temp = { i, max };val.add(temp);} else if (arry[i][j] > max) {max = arry[i][j];val.clear();int[] temp = { i, max };val.add(temp);}} else {arry[i][j] = 0;}}}HashSet<String> hs = new HashSet<String>();if (val.isEmpty())return hs;for (int[] in : val) {int index = in[0];int len = in[1];String s = "";while (len-- > 0) {s = cl[index--] + s;}hs.add(s);}return hs;}public static void main(String[] args) {/** * 结果:sdfe */String l = "deasdfe1ra";String h = "unnasdsdfew333";for (String s : foo(l, h)) {System.out.println(s);}System.out.println();/** * 结果: * 123 * dde */l = "123kdde123";h = "123gddedde";for (String s : foo(l, h)) {System.out.println(s);}}}






0 0