簡體   English   中英

字符串出現在另一個字符串中的次數

[英]How many times string appears in another string

我有一個不會改變的大型靜態二進制文件(10GB)。

我希望能夠將小字符串(每個15字節或更低)作為輸入,然后確定哪個字符串最不頻繁。

我明白,如果沒有實際搜索整個二進制文件,我將無法確切地確定它,所以我知道它將是一個近似值。

構建樹/哈希表是不可行的,因為它需要大約256 ^ 15個字節,這是ALOT。

我有大約100GB的磁盤空間和8GB的RAM將專門用於這個任務,但我似乎找不到任何方法來完成這項任務,而不實際翻閱文件。

我有足夠的時間來准備大二進制文件,之后我需要多次決定哪個是頻率最低的字符串。

有任何想法嗎?

謝謝! 丹尼爾。

(順便說一句:如果重要的話,我正在使用Python)

也許構建一個哈希表,其中包含n-tuples的數量,因為你可以負擔得起存儲? 您可以修剪不再出現的樹木。 我不會稱之為“近似”,但可以是“上限”,保證檢測不出現的字符串。

所以,假設您可以構建所有4元組。

然后計算“ABCDEF”的出現次數,你有最小計數(ABCD),計數(BCDE),計數(CDEF)。 如果其中任何一個為零,則保證不會出現該字符串。 如果它是一個,它最多會出現一次(但可能根本不出現)。

因為你有一個不會改變的大型靜態字符串,你可以區分一次性工作,預處理這個從不必重復的字符串,從回答查詢的工作。 在功能更強大的機器上進行一次性工作可能會很方便。

如果你能找到一個具有一個數量級或更多內部存儲的機器,你可以構建一個后綴數組 - 一個偏移量數組,以從偏移量開始的后綴的排序順序進入流。 這可以存儲在外部存儲器中以進行查詢,您可以使用二進制搜索來查找查詢字符串出現的排序順序中的第一個和最后一個位置。 顯然,兩者之間的距離將為您提供出現的次數,並且二進制搜索將需要大約34個二進制字符串來進行16 Gbyte,假設16Gbytes是2 ^ 34字節,因此每個查詢應該花費大約68個磁盤搜索。

期望你找到那么多的內部存儲空間可能是不合理的,但我剛買了一個1TB的USB硬盤驅動器大約50磅,所以我認為你可以增加一次性工作的外部存儲空間。 外部存儲器中有后綴數組構造的算法,但由於查詢字符串限制為15個字節,因此不需要任何復雜的內容。 只需通過寫出每個偏移量后跟一個5字節偏移量的15字節字符串來創建200GB數據,然后使用外部排序對這些20字節記錄進行排序。 這將按排序順序為字符串提供50Gbytes的索引,以便您將其放入外部存儲器以回答查詢。

如果您事先知道所有查詢,或者准備將它們批處理,另一種方法是從它們構建一個http://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_string_matching_algorithm樹。 這在查詢的總大小中需要時間線性。 然后,您可以按照與該數據大小和任何字符串找到匹配項的次數之和成比例的時間流式傳輸10GB數據。

因為您正在尋找哪種頻率最低,並且願意接受近似解決方案。 您可以使用一系列Bloom過濾器而不是哈希表。 如果使用足夠大的那些,則不必擔心查詢大小,因為您可能會將誤報率保持在較低水平。

我們的想法是遍歷所有可能的查詢大小並從中創建子字符串。 例如,如果查詢將在3和100之間,那么它將花費(N *((i)的總和從i = 3到i = 100))。 然后逐個將子集添加到其中一個布隆過濾器,這樣查詢在過濾器中不存在,如果需要,創建一個具有相同散列函數的新Bloom過濾器。 您可以通過遍歷每個過濾器並檢查其中是否存在查詢來獲取計數。 然后,每個查詢只需通過每個過濾器並檢查它是否在那里,如果是,則為計數加1。

您需要嘗試平衡誤報率和過濾器數量。 如果其中一個過濾器上的誤報率過高則沒有用,如果你有數萬億個過濾器(如果每個子串有一個過濾器,則很可能)。 有幾種方法可以解決這些問題。

  • 要減少過濾器的數量:
    1. 隨機刪除過濾器,直到只剩下這么多。 這可能會增加誤報率,這可能意味着最好簡單地刪除具有最高預期誤報率的過濾器。
    2. 隨機合並過濾器,直到剩下這么多。 理想情況下避免過於頻繁地合並過濾器,因為它會增加誤報率。 實際上,如果不使用可擴展版本(參見下文),你可能有太多這樣做,因為它可能很難管理誤報率。
    3. 添加到bloom過濾器時避免貪婪的方法也可能不是一件壞事。 相當具有選擇性,可以添加過濾器。

您可能最終必須實現可擴展的布隆過濾器以保持可管理性,這聽起來類似於我的建議,所以應該工作得很好。

暫無
暫無

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

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