Fastest way to match substring from large dict
我有一些(通常 < 300 个符号长度)字符串,例如 'aabbccdcabcbbacdaaa'。
有一个 python 字典,其中键是类似格式的字符串,例如'bcccd',密钥长度从 10 到 100 个符号不等。字典有 50 万个条目。
我需要将我的初始字符串与字典的值相匹配,或者找出字典中没有正确的值。匹配条件:字典键应该在字符串中的某处(严格匹配)。
就计算速度而言,最好的方法是什么?
我觉得应该有一些棘手的方法来散列我的初始字符串和字典键,以应用一些巧妙的子字符串搜索方法(如 Rabin-Karp 或 Knuth-Morris-Pratt)。或者后缀树状结构可能是一个很好的解决方案?
刚刚为 Python 找到了一个合理的 Aho-Corasick 实现 - pyahocorasick。取自页面末尾的示例:
1 2 3 4 5 6 7 8 9 | import ahocorasick A = ahocorasick.Automaton() for k, v in your_big_dict.iteritems(): A.add_word(k, v) A.make_automaton() for item in A.iter(your_long_string): print(item) |
1 2 3 4 5 6 7 8 9 10 11 | def search(string, dict_search): # If those 2 lines are too expensive, calculate them and pass as arguments max_key = max(len(x) for x in dict_search) min_key = min(len(x) for x in dict_search) return set( string[x:x+i] for i in range(min_key, max_key+1) for x in range(len(string)-i+1) if string[x:x+i] in dict_search ) |
跑步:
1 2 | >>> search('aabbccdcabcbbacdaaa', {'aaa', 'acd', 'adb', 'bccd', 'cbbb', 'abc'}) {'aaa', 'abc', 'acd', 'bccd'} |
您可以使用以下格式:
1 2 3 | for key in your_dictionary: if key in your_string: print(key+' is in both your string and the dictionary. It has the value '+str(your_dictionary[key])) |
如果您想以任何方式对此进行更改,请在评论中告诉我,我很乐意更新。