我认为这里的关键思想是有某种索引提供从规范的字符序列到实际单词的映射。像这样的东西:
# List of known words
>>> words = ('bonjour', 'jour', 'bon', 'poire', 'proie')
# Build the index
>>> index = collections.defaultdict(list)
>>> for w in words:
... index[''.join(sorted(w.lower()))].append(w)
...
这将产生一种有效的方法来查找与字符序列相对应的所有字谜:
>>> index
defaultdict(<class 'list'>, {'joru': ['jour'], 'eiopr': ['poire', 'proie'], 'bjnooru': ['bonjour'], 'bno': ['bon']})
您可以这样查询索引:
>>> user_str = 'OIREP'
>>> index.get(''.join(sorted(user_str.lower())), "")
['poire', 'proie']
当然,这只会找到“精确”的字谜——即包含用户提供的所有字母。要查找与用户提供的字符串的子集匹配的所有字符串,您必须一次删除一个字母并再次检查每个组合。我觉得递归将有助于解决这个问题;)
编辑:(
我应该把它放在剧透部分吗?)
这是一个可能的解决方案:
import collections
words = ('bonjour', 'jour', 'bon', 'or', 'pire', 'poire', 'proie')
index = collections.defaultdict(list)
for w in words:
index[''.join(sorted(w.lower()))].append(w)
# Recursively search all the words containing a sequence of letters
def search(letters, result = set()):
# Assume "letters" ordered
if not letters:
return
solutions = index.get(letters)
if solutions:
for s in solutions:
result.add(s)
for i in range(0,len(letters)):
search(letters[:i]+letters[i+1:], result)
return result
# Use case:
user_str = "OIREP"
s = search(''.join(sorted(user_str.lower())))
print(s)
生产:
set(['poire', 'or', 'proie', 'pire'])
它不是那么糟糕,但可以改进,因为相同的字符子集被检查了几次。当用户提供的搜索字符串包含多个相同的字母时尤其如此。