简体   繁体   English

如何确定一个列表是否以相同的顺序包含在另一个列表中(在Java中)?

[英]How can I determine whether one list is contained in another, in the same order (in Java)?

Suppose I have three lists: 假设我有三个列表:

list1 = a, c, d, r, t list1 = a,c,d,r,t

list2 = a, d, t list2 = a,d,t

list3 = a, r, d list3 = a,r,d

Then list2 is contained in list1 but list3 is not because it is not in the same order. 然后, list2包含在list1中,list3不是,因为它的顺序不相同。

I checked isSubCollection() from CollectionUtils in Apache Commons, and the containsAll() method, but it seems that they don't consider order. 我检查了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();
}

This algorithm is linear and requires only 1 iteration in sup list. 这种算法是线性的,只需要1次迭代sup列表。

UPDATE 更新
If you use linked lists, get operation may run in O(n). 如果使用链接列表,则get操作可能在O(n)中运行。 So you can use 2 iterators: 因此,您可以使用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;
} 

But it looks uglier. 但是看起来很丑。

Not very efficient but... 效率不高,但是...

You can grab one item in list2 and iterate list1 until you find it or you reach the end of the list. 您可以在list2中抓取一个项目并迭代list1,直到找到它或到达列表的末尾。 If you do find it, save the index where you found it. 如果找到它,请将索引保存在找到它的位置。

Advance in list2, and iterate list1 from the first index forward. 在list2中前进,并从第一个索引开始迭代list1。

If you get to the end of list2, it's a sub-list by your criteria. 如果到达list2的末尾,则根据您的条件,这是一个子列表。

If you get to the end of list1 and haven't exausted list2, it ain't. 如果您到达list1的末尾并且还没有浏览list2,则不是。

It's not too difficult to whip up on your own. 自己动手并不难。

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;
}

That takes time O(sup.size() + sub.size()), which is optimal in general. 这需要时间O(sup.size()+ sub.size()),这通常是最佳的。

The approach required here is the same independent of language, though you at least need to be sure that it's possible to achieve your goal in Java. 尽管您至少需要确保可以使用Java实现目标,但此处所采用的方法与语言无关,但它们相同。 The solution is easier to describe using pointers from the C or C++ language, but I'll try to use more general terms here. 使用C或C ++语言的指针更容易描述该解决方案,但是我将在这里尝试使用更通用的术语。

Start with the first character of the "containing list" and the "contained list." 从“包含列表”和“包含列表”的第一个字符开始。

  • If the two characters match, advance to the next character of both lists. 如果两个字符匹配,请前进到两个列表的下一个字符。

    • If you reached the end of the "contained list," the answer is yes, it is contained within the other list. 如果达到了结束“载列表中,”答案是肯定的,它包含在其他列表中。

      Otherwise, if you reached the end of the "containing list," the answer is no, it does not contain the "contained list." 否则,如果到达“包含列表”的末尾,则答案为“否”,它包含“包含列表”。

      Otherwise, repeat the process with the two now-current characters. 否则,请使用两个当前字符重复该过程。

  • Otherwise, advance to the next character of the "containing list," and try again against the same character of the "contained list." 否则,请前进到“包含列表”的下一个字符,然后再次尝试对“包含列表”的相同字符。

    • If you reach the end of the "containing list," the answer is no, it does not contain the "contained list." 如果到达“包含列表”的末尾,则答案为否,它包含“包含列表”。

      Otherwise, repeat the process with the two now-current characters. 否则,请使用两个当前字符重复该过程。

If you draw two arrows ("pointers") to the characters in each list on paper, and only ever bump the arrow in the "contained list" to the right when it matches a character in the "containing list," and bump the arrow in the "containing list" to the right on every step, you'll see how the possibilities for matching success and failure play out. 如果您在纸上每个列表中的字符上绘制两个箭头(“指针”),并且只在与“包含列表”中的字符匹配时将“包含列表”中的箭头与右侧相碰,然后对箭头进行凹凸处理在一步右侧的“包含列表”中,您将看到匹配成功和失败可能性的方式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何使用java中的list Structures确定java中当前元素之后是否存在其他元素 - 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 verify that a list elements are in same order of another list or not? 如何通过反射确定Java类是否是抽象的 - How can I determine whether a Java class is abstract by reflection 如何判断安装的 Java 是否支持模块? - How can I determine whether the installed Java supports modules or not? 如何对一个数组列表进行排序,并在java中设置另一个具有相同顺序的列表 - How to sort one array list and set the another list with same order in java java - 如何知道一个数字是否包含在另一个数字中? - How can I know if a number is contained in another in java? 如何以相同顺序在另一个列表中声明一个列表 - How do assert one list in another list with same order 一个设备如何使用 J2ME 确定另一个设备的蓝牙是否已连接? - How can one device determine whether another's Bluetooth is connected, using J2ME? 有没有更好的方法来验证一个循环列表是否包含在 Java 中的另一个循环列表中? - Is there a better way to verify that one looped list is contained in another in Java? 如何确定给定 jar 的 org 和包含的包的名称? - How can I determine the org of a given jar and the names of contained packages?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM