我的字符串列表如下所示:
List<String> parentDataList: {"this", "is", "a", "test", "string", "and", "a", "test", "other"}
List<String> child1: {"a", "test"}
List<String> child2: {"this", "string"}
List<String> child3: {"is", "a", "test"}
我的期望是我想检查父列表是否包含序列子列表,然后在子列表的父列表中获取开始和结束索引。
从上面的例子:
Parent contain child1 list, and return the indexes: [2 - 3] and [6 - 7]
Parent doesn't contain child2 list because it isn't sequential.
Parent contain child3 list, and return the index: [1 - 3]
我尝试使用List.containsAll
方法,但它并不关心列表项的顺序,我无法从此方法获取开始和结束索引。
我正在寻找最快的方法,因为我的列表有很多数据,我必须从许多输入字符串中搜索。
任何帮助将不胜感激!
更新:
我需要获取子列表的所有索引都包含在父列表中。例如,父级包含两个位置的child1:[2 - 3]和[6 - 7]
答案 0 :(得分:8)
方法Collections.indexOfSubList
将为您提供所需的信息。
返回指定源列表中指定目标列表第一次出现的起始位置,如果不存在,则返回-1。 更正式地,返回最低索引i,使得source.subList(i,i + target.size())。equals(target),或者如果没有这样的索引则返回-1。 (如果target.size()&gt; source.size(),则返回-1。)
int index=Collections.indexOfSubList(parentDataList, child1);
…
索引间隔从index
开始,包括index+child1.size()
,不包括-1
。当然,除非返回的索引是{{1}}。在后一种情况下,找不到子列表。
答案 1 :(得分:2)
您可以像这样更改@ Alessio的代码。它也适用于你的案件。
public List<Interval> getIntervals(String[] parent, String[] child) {
List<Interval> intervals = new ArrayList<Interval>();
Interval interval = new Interval();
for (int i = 0, j = 0; i < parent.length; i++) {
if (child[j].equals(parent[i])) {
j++;
if (j == 1) {
interval.start = i;
}
if (j == child.length) {
interval.end = i;
intervals.add(interval);
interval = new Interval();
j = 0;
}
} else {
j = 0;
}
}
return intervals;
}
答案 2 :(得分:1)
如果您想手动执行此操作:
public static List<Interval> getIntervals2(String[] parent, String[] child) {
List<Interval> intervals = new ArrayList<Launch.Interval>();
for (int i = 0; i < parent.length; i++) {
if (child[0].equals(parent[i])) {
Interval interval = new Interval();
interval.start = i;
intervals.add(interval);
}
}
ListIterator<Interval> iterator = intervals.listIterator();
while (iterator.hasNext()) {
Interval interval = iterator.next();
for (int j = 1, i = interval.start + 1; i < child.length; i++, j++) {
if (!child[j].equals(parent[i]))
iterator.remove();
}
if (interval.start + child.length - 1 < parent.length - 1)
interval.end = interval.start + child.length - 1;
else
iterator.remove();
}
return intervals;
}