两个字符串查找最大公共子串
查找两个字符串的最大公共子串
方法一:LCS
步骤:
1、根据两个字符串长度构建一个同等长度的二维数组(假设字符串1作为行,字符串2作为列)
2、遍历数据行列,比较两个字符串在数组对应行列节点位置的字符是否相等,如果相等将数组这个位置的值设为左上角元素值+1(arry[i][j]+1),(第一行或第一列的元素需要置为1),这个数字代表了公共字符串的长度。
3、遍历完成后将最后的两个字符相等的位置的数字大小记录下来作为公共串长度,将最后一次相等时行(列)下标记录下来,作为字符串1子序列的起始位置(如果记录的是列,则是字符串2子序列其实位置)。
实例:
String a="abcdf";
String b="rtbcdef";
/*查找公共子串*/ public String lastComStr(String str1, String str2) { /*公共串最大长度*/ int maxlen=0; /*公共串最后结束的位置*/ int endlen=0; int str1len=str1.length(); int str2len=str2.length(); int[][] arry=new int[str1len][str2len]; for (int i=0;i<str1len;i++){ for (int j=0;j<str2len;j++){ if (str1.charAt(i)==str2.charAt(j)){ if (0==i||j==0){ arry[i][j]=1; }else { /*arry[i][j]等左上角数字加一*/ arry[i][j]=1+arry[i-1][j-1]; } } if (maxlen<arry[i][j]){ maxlen=arry[i][j]; endlen=i; } } } /*[start,end) 字符串截取到start-end,调用substring(start,end+1)取出的字符串才是start-end的范围 */ return str1.substring(endlen-maxlen+1,endlen+1); }
方法二:(暴力算法)
步骤一:找出最短字符串
步骤二:找出最短字符串的全部子串,长度为1,2,3,4...n的,例如:a,b,c,d,f,ab,bc,cd,df,...。
步骤三:另一个字符串包含这些子串的最长的那一个。
public static String longestCommonSubsequence(String text1, String text2) { String maxstr = ""; String shortstr = text1.length() < text2.length() ? text1 : text2; String langstr = text1.length() > text2.length() ? text1 : text2; int length = shortstr.length(); for (int i = 0; i < length; i++) { for (int j = i + 1; j <= length; j++) { String str = shortstr.substring(i, j); if (langstr.contains(str) && str.length() > maxstr.length()) { maxstr = str; } } } return maxstr; }