就像现在一样,搜索的主要部分将是检查wordDict 中的每个键与模式。我能想到的一种优化是减少这种搜索。
首先我构建“元”字典,其中键是 frozenset 的字符 wordDict 的键和值是 wordDict 键的列表。
在getKey() 中,使用这个元字典,我只检查可能匹配的键(所以不是所有键)。
import re
from itertools import chain, combinations
def powerset(iterable):
"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
def getKey(string, pat, meta):
k = ''.join(sorted(set(string)))
expr = re.compile(pat)
return [elem for elem in meta[frozenset(k)] if expr.match(elem)] # <--- here I search only valid keys (keys where there's possibility of match)
wordDict = {'AADFLORW':['value1'], 'AAAGRU': ['VAL1', 'SOME DIFFERENT VALUE']}
# build meta information about wordDict.keys()
# This could take a while!!!
meta = {}
for k in wordDict.keys():
for p in powerset(set(k)):
if p:
meta.setdefault(frozenset(p), []).append(k)
# from pprint import pprint
# pprint(meta)
m = re.compile(r'[a-zA-Z]').findall('ADOLF') # I'm searching ADOLF in the keys
pat = '.*' + '(.*)'.join(sorted(m)) + '.*'
for key in getKey('ADOLF', pat, meta):
print(key)
打印:
ADFLORW
为了说明,“元”字典现在看起来像这样:
{frozenset({'A'}): ['AADFLORW', 'AAAGRU'],
frozenset({'D'}): ['AADFLORW'],
frozenset({'L'}): ['AADFLORW'],
frozenset({'R'}): ['AADFLORW', 'AAAGRU'],
frozenset({'W'}): ['AADFLORW'],
frozenset({'O'}): ['AADFLORW'],
frozenset({'F'}): ['AADFLORW'],
frozenset({'A', 'D'}): ['AADFLORW'],
frozenset({'A', 'L'}): ['AADFLORW'],
frozenset({'A', 'R'}): ['AADFLORW', 'AAAGRU'],
frozenset({'W', 'A'}): ['AADFLORW'],
...
它可能相当大,所以现在你正在用“空间”换取“速度”。