簡體   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