簡體   English   中英

針對一系列集合檢查子集的高效算法

[英]Efficient algorithm to check for subset against a range of sets

我通讀了一些關於確定集合A是否是另一個集合B的子集的帖子。 但是我發現很難確定使用什么算法。 這是問題的概述:

  • 我有一個字符串數組A ,我在程序開始時收到它。 對該結構知之甚少。 數組中的每個字符串可以任意長,條目數不受限制。 盡管通常可以假定數組中的條目數不會太大 (< 100)。
  • 然后我遍歷長度為n的對象列表。
  • n對象中的每一個也將有一個字符串數組B ,即會有n B數組。 一旦程序運行, B將被固定,即它們在運行期間不會改變。
  • 我想為每個對象確定A是否是B的子集。

現在,我想到了哈希表。 但是,在我看來,只有只有一個B和很多A時,它們才會有效。 然后我可以為B創建一個哈希表,並根據我的哈希表檢查每個對象的每個字符串數組。 但事實並非如此,因為只有一個A而不是n B 執行此操作的有效算法是什么?

例子:

A:  ["A", "G", "T"]
B1: ["C", "G"]
B2: ["K", "A", "U", "T", "G"]
.
.
.
Bn: ["T", "I", "G", "O", "L"]

這里AB2的子集,但不是B1的子集,也不是Bn的子集。

一種有效的方法是將集合 A 表示為一個特里樹。 這允許檢查給定字符串是否在時間上與字符串長度成線性關系。

如果它屬於 A,那么沒有更好的方法然后徹底檢查所有 Bi 和 Bi 中的所有字符串。一旦匹配了 A 中的所有字符串(在找到字符串時標記一個字符串),搜索就會停止。

運行時間與所有 B 中所有字符串中的字符總數成正比。在實踐中,很大一部分字符將被跳過,因為

  • 搜索不在 A 中的字符串可以提前終止,

  • 即使 Bi 中還剩下字符串,子集測試也可以得出肯定的結論,

  • 當 A 中未匹配的字符串多於 Bi 中剩余的字符串時,子集測試可能得出否定結論。

這種方法肯定是最壞情況下的最優方法,因為您最多讀取一次字符並對每個字符執行恆定數量的操作。

正如您事先知道A ,您可以設計一個無沖突哈希函數來哈希A所有元素。

然后只對搜索步驟中的散列進行操作,而不是對字符串進行操作。 對於 B 的每個元素,計算它的散列,然后用它來查找 A 的元素。如果找到一個元素,則意味着散列匹配; 那么您還需要比較字符串以檢測它是真陽性還是偶然匹配。

計算匹配的數量。 當該數字等於 A 的大小時,停止並返回正結果。 如果 B 的所有元素都已處理並且匹配的數量小於 A 的大小,則返回否定結果。

作為第一種方法,我會預先計算集合的一些一般屬性,這(希望)能讓您快速過濾一些B 這些可能是,例如:

  • 一些字符串——如果 A 包含的元素多於B ,那么A肯定不能是B的子集;
  • 最長字符串的長度——如果A中最長的字符串比B中最長的字符串長,則A肯定不是B的子集;
  • 字符串長度的總和。

為了便於檢查,您可能需要按字母順序排列每組。 這將允許在通過兩組字符串的(線性)掃描中根據單個B檢查A

對於小A和大的B集合,使用二分搜索而不是線性掃描在B中查找字符串可能更有效; 這也需要對B進行預排序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM