以上的解决方案非常好,但是如果关键字字典很长,它很容易变得混乱(可能无法实现)。在
我建议将关键字存储在树中(它利用冗余),并且更节省空间。在
如果关键字是["art,"at","atm","bus","can","car"],则字典如下所示.
^
/ ¦ \
/ ¦ \
a b c
^ ^ ^
/ \ \ \
r t u a
^ ^ ^ ^
/ / \ \ / \
t m /0 s n r
^ ^ ^ ^ ^
/ / \ \ \
/0 /0 /0 /0 /0
我把它改成二进制,因为它更容易画画。节点"/0"具有词尾(虚拟字符)的意义,"."是根。在
我实现了这个简单的树类来构建树和必要的函数
^{pr2}$
给定关键字,我们可以用这样的代码构造结构keywords = ["car","at","atm","bus"]
keywordsTree = Tree('')
for keyword in keywords:
keywordsTreeNode = keywordsTree
for character in keyword:
if not keywordsTreeNode.has_child(character):
keywordsTreeNode.add_child(Tree(character))
keywordsTreeNode = keywordsTreeNode.get_child(character)
keywordsTreeNode.add_child(Tree('/0'))
最后,我们在输入中搜索关键字。下面的解决方案为输入中的给定位置提供从该位置开始匹配的所有关键字。在inputWords = "xyzcarbusabccar8hj/0atm"
output = []
lengthInput = len(inputWords)
for position in range(0,lengthInput):
##add by default the character
# allMathcedKeyWords = [inputWords[position]]
allMathcedKeyWords = []
keywordsTreeNode = keywordsTree
searchPosition = position
curMathcedWord = ''
while searchPosition < lengthInput and keywordsTreeNode.has_child(inputWords[searchPosition]) :
keywordsTreeNode = keywordsTreeNode.get_child(inputWords[searchPosition])
curMathcedWord = curMathcedWord + inputWords[searchPosition]
if (keywordsTreeNode.has_child("/0")):
allMathcedKeyWords.append(curMathcedWord)
searchPosition += 1
if len(allMathcedKeyWords)==0:
allMathcedKeyWords = inputWords[position]
output.append(allMathcedKeyWords)
print output
这个代码输出这个['x', 'y', 'z',
['car'],
'a', 'r',
['bus'],
'u', 's', 'a', 'b', 'c',
['car'],
'a', 'r', '8', 'h', 'j', '/', '0',
['at', 'atm'],
't', 'm']
对于上面的代码来说,重要的是单词末尾的虚拟字符是两个字母("/0"),并且永远不会匹配(即使组合出现在上面详述的输入序列中)。此外,它还处理任何字符串字符(对于输入和关键字-也不需要像re.findall()中那样引入转义字符)
从这个输出列表中,您可以决定要做什么。如果您想要re.findall的解决方案,请为某个位置找到最长匹配的单词(或基于关键字逻辑顺序),并向前跳转该单词包含的字符数。在
问题更进一步,输入中的每个字符都是一个顶点,当你找到一个单词时,在匹配单词的最后一个字符后,从该位置添加一条边到对应的下一个顶点。最短路径算法将再次给你上述的解决方案。这样构造输出将再次带来空间效率,并为更复杂的算法打开了大门。在
例如,有关键字"car"和"art",以及art和input sequence"acart",结果图如下所示______________
¦ ¦
- a -> c -> a -> r -> t ->
¦______________¦
复杂性分析Space : longest_word_length * number_of_letters_in_keywords
input_length + input_length * input_length (worst case-fully connected graph)
Time : input_length * longest_word_length
input_length + input_length * input_length (worst case-fully connected graph)