![](/img/trans.png)
[英]How I can determine if there is another element after the current one or not in java using list Structures in java
[英]How can I determine whether one list is contained in another, in the same order (in Java)?
假设我有三个列表:
list1 = a,c,d,r,t
list2 = a,d,t
list3 = a,r,d
然后, list2包含在list1中,但list3不是,因为它的顺序不相同。
我检查了Apache Commons中CollectionUtils
isSubCollection()
和containsAll()
方法,但似乎它们不考虑顺序。
boolean isSubsequence(List<?> sup, List<?> sub) {
int current = 0;
for (Object obj: sup) {
if (current == sub.size()) {
return true;
}
if (obj.equals(sub.get(current)) {
current++;
}
}
return current == sub.size();
}
这种算法是线性的,只需要1次迭代sup
列表。
更新
如果使用链接列表,则get
操作可能在O(n)中运行。 因此,您可以使用2个迭代器:
boolean isSubsequence(List<?> sup, List<?> sub) {
Iterator<?> supIt = sup.iterator();
for (Iterator<?> subIt = sub.iterator(); subIt.hasNext();) {
Object current = subIt.next();
boolean found = false;
while (supIt.hasNext() && !found) {
found |= supIt.next().equals(current);
}
if (!found) {
return false;
}
}
return true;
}
但是看起来很丑。
效率不高,但是...
您可以在list2中抓取一个项目并迭代list1,直到找到它或到达列表的末尾。 如果找到它,请将索引保存在找到它的位置。
在list2中前进,并从第一个索引开始迭代list1。
如果到达list2的末尾,则根据您的条件,这是一个子列表。
如果您到达list1的末尾并且还没有浏览list2,则不是。
自己动手并不难。
boolean isSubSequence(List<?> sup, List<?> sub) {
for (Object o : sub) {
int index = sup.indexOf(o);
if (index == -1) { return false; }
sup = sup.subList(index + 1, sup.size());
}
return true;
}
这需要时间O(sup.size()+ sub.size()),这通常是最佳的。
尽管您至少需要确保可以使用Java实现目标,但此处所采用的方法与语言无关,但它们相同。 使用C或C ++语言的指针更容易描述该解决方案,但是我将在这里尝试使用更通用的术语。
从“包含列表”和“包含列表”的第一个字符开始。
如果两个字符匹配,请前进到两个列表的下一个字符。
如果达到了结束“载列表中,”答案是肯定的,它包含在其他列表中。
否则,如果到达“包含列表”的末尾,则答案为“否”,它不包含“包含列表”。
否则,请使用两个当前字符重复该过程。
否则,请前进到“包含列表”的下一个字符,然后再次尝试对“包含列表”的相同字符。
如果到达“包含列表”的末尾,则答案为否,它不包含“包含列表”。
否则,请使用两个当前字符重复该过程。
如果您在纸上每个列表中的字符上绘制两个箭头(“指针”),并且只在与“包含列表”中的字符匹配时将“包含列表”中的箭头与右侧相碰,然后对箭头进行凹凸处理在每一步右侧的“包含列表”中,您将看到匹配成功和失败可能性的方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.