有个需求是对两个人的运动轨迹进行分析判断是否有过接触,运动轨迹是一个字符串或者数组。详细的需求就不透露了,但其中会涉及到求在两个字符串都出现的部分,也就是交集 。下面是实现方法
package yulisao.test;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
public class FindStr {
public static void main(String[] args) {
String str1 = "我是张三的老朋友";
String str2 = "张三是没有朋友的";
List<String> list = findRepeatStr(str1,str2);
if (CollectionUtils.isNotEmpty(list)) {
list.forEach(info -> System.out::println);
}
}
private static List<String> findRepeatStr(String str1, String str2) {
List<String> list = new ArrayList();
if (StringUtils.isBlank(str1) || StringUtils.isBlank(str1)) {
return list;
}
String min = (str1.length() < str2.length()) ? str1 : str2; // 比较短的字符串
String max = (str1.length() >= str2.length()) ? str1 : str2; // 比较长的字符串
/*
第一个循环的i每次加1加上第二个循环的y = min.length() - i表示第一个循环每次循环短的字符串会少一个字符,即对短字符串进行拆解截取,长度为8的字符串能截取出多少种组合,长度为7的字符串能截取出多少种组合,长度为6的字符串能截取出多少种组合...
第二个循环括号里面的条件是具体实现当前长度下能截取出多少种组合,以y <= min.length()作为终止条件。以截取长度为2的有多少种组合为例,即0-2位,1-3位,2-4位... 直到短字符串的末尾字符为止(截取短字符串的第x位到末尾min.length()为止)
然后把截取好的字符与长的字符比较是否被包含,包含即重叠
*/
// 把短的字符串依次递减一个字符进行截取组合
for (int i = 0; i < min.length(); i++) {
System.out.println("第" + i + "次循环,从短的字符串种截取长度为" + (min.length() - i) + "的组合如下:");
for (int x = 0, y = min.length() - i; y <= min.length(); x++, y++) {
String sub = min.substring(x,y); // 得到第x个长度为y的截取
System.out.println(sub);
if (max.contains(sub)) { // 若子串被包含于长串中,说明是重复字符串
if (sub.length() > 1)
list.add(sub);
}
}
}
return list;
}
}
其中两个for循环以及注释如果难以理解,可以看下面的详细运行步骤
- 第1次循环,短字符串进行组合,组合元素的长度为短字符串的长度-0,此时只有本身一种组合
- 第2次循环,短字符串进行组合,组合元素的长度为短字符串的长度-1,此时有C7/8种组合(7,8分别是C的上标和下标,下同),即第0-7位、1-8位
- 第3次循环,短字符串进行组合,组合元素的长度为短字符串的长度-2,此时有C6/8种组合,即第0-6位、第1-7位、第2-8位
- 第4次循环,短字符串进行组合,组合元素的长度为短字符串的长度-3,此时有C5/8种组合,即第0-5位、第1-6位、第2-7位、…
- …
- 最后一次循环,短字符串进行组合,组合元素的长度为短字符串的长度-7,此时有C1/8种组合,即第0-1位、第1-2位、第2-3位、…
控制台运行结果如下
第0次循环,从短的字符串种截取长度为8的组合如下:
张三是没有朋友的
第1次循环,从短的字符串种截取长度为7的组合如下:
张三是没有朋友
三是没有朋友的
第2次循环,从短的字符串种截取长度为6的组合如下:
张三是没有朋
三是没有朋友
是没有朋友的
第3次循环,从短的字符串种截取长度为5的组合如下:
张三是没有
三是没有朋
是没有朋友
没有朋友的
第4次循环,从短的字符串种截取长度为4的组合如下:
张三是没
三是没有
是没有朋
没有朋友
有朋友的
第5次循环,从短的字符串种截取长度为3的组合如下:
张三是
三是没
是没有
没有朋
有朋友
朋友的
第6次循环,从短的字符串种截取长度为2的组合如下:
张三
三是
是没
没有
有朋
朋友
友的
第7次循环,从短的字符串种截取长度为1的组合如下:
张
三
是
没
有
朋
友
的