[英]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"]
這里A
是B2
的子集,但不是B1
的子集,也不是Bn
的子集。
一種有效的方法是將集合 A 表示為一個特里樹。 這允許檢查給定字符串是否在時間上與字符串長度成線性關系。
如果它屬於 A,那么沒有更好的方法然后徹底檢查所有 Bi 和 Bi 中的所有字符串。一旦匹配了 A 中的所有字符串(在找到字符串時標記一個字符串),搜索就會停止。
運行時間與所有 B 中所有字符串中的字符總數成正比。在實踐中,很大一部分字符將被跳過,因為
搜索不在 A 中的字符串可以提前終止,
即使 Bi 中還剩下字符串,子集測試也可以得出肯定的結論,
當 A 中未匹配的字符串多於 Bi 中剩余的字符串時,子集測試可能得出否定結論。
這種方法肯定是最壞情況下的最優方法,因為您最多讀取一次字符並對每個字符執行恆定數量的操作。
正如您事先知道A
,您可以設計一個無沖突哈希函數來哈希A
所有元素。
然后只對搜索步驟中的散列進行操作,而不是對字符串進行操作。 對於 B 的每個元素,計算它的散列,然后用它來查找 A 的元素。如果找到一個元素,則意味着散列匹配; 那么您還需要比較字符串以檢測它是真陽性還是偶然匹配。
計算匹配的數量。 當該數字等於 A 的大小時,停止並返回正結果。 如果 B 的所有元素都已處理並且匹配的數量小於 A 的大小,則返回否定結果。
作為第一種方法,我會預先計算集合的一些一般屬性,這(希望)能讓您快速過濾一些B
。 這些可能是,例如:
B
,那么A
肯定不能是B
的子集;A
中最長的字符串比B
中最長的字符串長,則A
肯定不是B
的子集; 為了便於檢查,您可能需要按字母順序排列每組。 這將允許在通過兩組字符串的(線性)掃描中根據單個B
檢查A
對於小A
和大的B
集合,使用二分搜索而不是線性掃描在B
中查找字符串可能更有效; 這也需要對B
進行預排序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.