获取两个字符串中最大相同子串
分析
比如有两个字符串
str1 = “eysdfghjkl”;
str2 = “cxbghjp”;
需要找出这里两个字符串中最大的字符子串,这里就是**“ghj”**.
查找的方法就是把两个字符串中较短的那个依次减小,然后按照该长度在短的字符串中获取所有子串依次判断该子串是否存在于长的字符串中.
上面的方法听着是不是很绕.我们详细说明一下吧.
- 上面的那两个字符串短的是str2,长度为7,即str2.leng() == 7.这个没有异议吧.
然后依次减小,先从7开始,str2长度为7的子串只有一个吧,就是str2本身.那判断str2是否是str1的子串.很明显不是.那我们就把上面黑体字部分的定义为第一轮 - 那我们开始第二轮,str2的长度依次减小,上一轮的长度为7,那这一轮就是6,那我们就找长度为6的str2的子串,只有两个:
(1) “cxbghj”
(2) “xbghjp”
然后判断上面这两个字符串的是否是str1的子串,也不是. - 继续开始第三轮,第三轮的长度为5,str2长度的子串有3个:
(1) “cxbgh”
(2) “xbghj”
(3) “bghjp”
判断这三个字符串是否是str1的子串.不是. - 第四轮,长度为4,四个str2的子串
(1) “cxbg”
(2) “xbgh”
(3) “bghj”
(4) “ghjp”
也没有是str1的子串. - 第5轮长度为3,5个str的子串.
(1) “cxb”
(2) “xbg”
(3) “bgh”
(4) “ghj”
(5) “hjp”
在这一轮对比到(4)的时候判断(4)是str1的子串.就马上退出,就找到了这两个字符串的子串
实现代码如下:
public static void main(String[] args) {
String str1 = "eysdfghjkl"; //定义两个字符串
String str2 = "cxbghjp";//定义两个字符串
System.out.println("最大子串为:" + findMaxSubString(str1,str2));
}
public static String findMaxSubString(String s1,String s2) {
String max = s1.length() > s2.length() ? s1 : s2; //查找长的字符串
String min = s1.length() > s2.length() ? s2 : s1; //查找短的字符串
for (int i = 0; i < min.length(); i++) {
/*第一个循坏是定义一共有多少轮,但不一定执行完全部的轮数才能找到,如果找到下面的return 会返回找到的子串*/
for (int j = 0,n = min.length() - i; n < min.length() + 1; j++,n++) {
/*第二个循坏中的 j 是获取str2中的子串都是从0开始的,而n 是用来计算在str2中获取子串的长度,第一轮是7,就是str2的长度减去0(我们可以想象成 str的长度 - 轮数1 - 1 = 7(就是从0到7获取str2的子串),如果是第二轮就是str的长度 - 轮数2 - 1 = 6)(就是从0到6获取str2的子串),而判断条件n < min.length() + 1 是用来获取有多少个子串,比如上面的6,获取了(0到6之后,还有一个是1到7的子串,在执行完一次循坏之后j和n会自加1,在第二次循环的时候j和n就会变成1和7,就能获取长度为6的第二个子串.长度为5,4也是依次计算)*/
String temp = min.substring(j, n); //根据长度获取str2的子串,这里要注意的是,并不能获取到n,也就是说获取的长度为[]j,n),因为substring函数是左闭右开的.
System.out.println(j + " " + n + " " + temp); //这里的打印是辅助,没用的
if(max.contains(temp)) //对比子串是否在str1中
return temp; //返回找到子串
}
}
return null;//如果没有找到return null
}
输出如下:
0 7 cxbghjp
0 6 cxbghj
1 7 xbghjp
0 5 cxbgh
1 6 xbghj
2 7 bghjp
0 4 cxbg
1 5 xbgh
2 6 bghj
3 7 ghjp
0 3 cxb
1 4 xbg
2 5 bgh
3 6 ghj
最大子串为:ghj
这样就能找到最大子串.