[英]Fast String within List Searching
使用Python 3,我有一個包含超過100,000個字符串(list1)的列表,每個字符串最多300個字符。 我還有一個包含超過900萬個子串的列表(list2) - 我想計算list2中子串的元素數量。例如,
list1 = ['cat', 'caa', 'doa', 'oat']
list2 = ['at', 'ca', 'do']
我希望函數返回(映射到list2):
[2, 2, 1]
通常,這非常簡單,只需要很少。 但是,由於列表的大小,我有效率問題。 我想找到返回該計數器列表的最快方法。
我已經嘗試過列表推導,生成器,地圖,各種循環,我還沒有找到一種快速的方法來完成這項簡單的任務。 理論上什么是完成這個目標的最快方法,最好快速采取O(len(list2))
步驟?
設置M = len(list1)
和N = len(list2)
對於list2
每個N條目,您將不得不對list1
中的條目進行M比較。 這是O(M x N)
的最壞情況運行時間。 如果你進一步使用,讓我們將list2
每個條目的長度為1, list1
每個條目的長度為300,那么你的運行時間為O(300M x N)
。
如果性能確實是一個問題,請嘗試動態編程。 這是一個開始:
1)按照長度的升序排序list2
,如下所示:
['scorch', 'scorching', 'dump', 'dumpster', 'dumpsters']
2)將它們分類為子列表,使得每個前面的條目都是前進條目的子集,如下所示:
[['scorch', 'scorching'] , ['dump', 'dumpster', 'dumpsters']]
3)現在如果你與list1
進行比較並且'scorch'
不在那里,那么你也不必搜索'scorching'
。 同樣,如果'dump'
不存在,那么'dumpster'
或'dumpsters'
都不是
注意最壞的情況下運行時間仍然是相同的
我相信這個任務可以通過Aho Corasick字符串匹配機器在線性時間內解決。 有關其他信息, 請參閱此答案 (也許您可以從該問題的其他答案中獲得想法 - 這幾乎是相同的任務,我認為Aho Corasick是解決此問題的理論上最快的方法)。
您將不得不以這種方式修改字符串匹配機器,而不是返回匹配,它將每個匹配的子字符串的計數器增加1。 (這應該只是一個小修改)。
不知道如何避免使用某種O(n ** 2)算法。 這是一個簡單的實現。
>>> def some_sort_of_count(list1, list2):
>>> return [sum(x in y for y in list1) for x in list2]
>>>
>>> list1 = ['cat', 'caa', 'doa', 'oat']
>>> list2 = ['at', 'ca', 'do']
>>> some_sort_of_count(list1, list2)
[2, 2, 1]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.