繁体   English   中英

如何确定一个列表是否以相同的顺序包含在另一个列表中(在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM