标签:
剧情提要:[工程师阿伟]正在和[机器小伟]一起研究[计算几何]]。
关于字典树的实现,已经有非常多的博文涉及到了。但基本都是用内嵌数组/列表实现的。
本博文是它的递归实现。
<span style="font-size:18px;">###
# @usage 字典树
# @author mw
# @date 2016年08月02日 星期二 08:56:34
# @param
# @return
#
###
class Trie:
class TrieNode:
def __init__(self,item,next = None, follows = None):
self.item = item
self.next = next
self.follows = follows
def __str__(self):
return str(self.item);
def getnext(self):
return self.next;
def setnext(self, next):
self.next = next;
def getfollows(self):
return self.follows;
def setfollows(self, follows):
self.follows = follows;
def getitem(self):
return self.item;
def setitem(self, item):
self.item = item;
def __iter__(self):
yield self.item;
if (self.follows != None):
for x in self.follows:
yield x;
def iternext(self):
yield self.item;
if (self.next != None):
for x in self.next.iternext():
yield x;
#从两个方向观察节点信息,一是从它的后续看,这是看一个单词
#另一个是从它的兄弟看,这是在这个点的各分支
def info(self, direction = 0):
s = '';
if direction == 0:
for x in self:
s += str(x)+'-->';
else:
for x in self.iternext():
s += str(x)+'-->';
print(s);
def __init__(self):
self.start = Trie.TrieNode('^', None, None);
def insert(self,item):
self.start = Trie.__insert(self.start,item)
def __contains__(self,item):
return Trie.__contains(self.start,item)
#生成诩根所在的结点
def __genNode(item):
if (len(item) == 1):
return Trie.TrieNode(item[0], None, None);
elif (len(item) > 1):
return Trie.TrieNode(item[0], None, Trie.__genNode(item[1:]));
else:
return None;
def __insert(node,item):
# This is the recursive insert function.
if (item == None or item == ''):
return None;
elif (node == None):
return Trie.__genNode(str(item));
elif (node.item == item[0]):
node.setfollows(Trie.__insert(node.getfollows(), item[1:]));
else:
node.setnext(Trie.__insert(node.getnext(), item));
return node;
def __contains(node, item):
# This is the recursive membership test.
#单词结尾用'$'分隔,当然,如果用其它分隔符,此处必须更改item+'$'
if Trie.__getNode(node, item) != None:
return True;
else:
return False;
#一般都是从字典的根结点开始遍历才有意义
def getNode(self, node, item):
return Trie.__getNode(node, item);
#找到某一节点
def __getNode(node, item):
if item == None or item == '':
return None;
elif node == None:
return None;
elif node.item != item[0]:
return Trie.__getNode(node.next, item);
else:
if (len(item) > 1):
return Trie.__getNode(node.follows, item[1:]);
else:
return node;
#遍历查看字典
def dict(self):
#单词结束的末尾标记
endChar = '$';
count = 0;
if (self.start != None):
cursor = self.start;
#具有后续节点的词段
dict_1 = [];
#最终版
dict_2 = [];
while cursor != None:
#if (cursor.follows == None):
if (cursor.follows == None):
#过滤掉词尾结束标记
dict_2.append(str(cursor.item)[:-1]);
else:
dict_1.append(str(cursor.item));
cursor = cursor.next;
while (len(dict_1) > 0):
a = dict_1.pop(0);
cursor = Trie.__getNode(self.start, a);
count+=1;
if (cursor != None):
cursor = cursor.follows;
while cursor != None:
if (cursor.follows == None):
dict_2.append((a+str(cursor.item))[:-1]);
else:
dict_1.append(a+str(cursor.item));
cursor = cursor.next;
print('找结点{0}次'.format(count));
print('字典:', dict_2);
else:
print('字典为空');
</span>
<span style="font-size:18px;">def main():
#计时开始
startTime = time.clock();
t = Trie();
a = ['I', 'love', 'lot', 'lance', 'you', 'you', 'love', 'me',
'i', 'have', 'a', 'book', 'you', 'have', 'a', 'pencil',
'pen', 'paper', 'lottol', 'banana'];
#插入单词,词尾加结束符
for i in range(len(a)):
t.insert(a[i]+'$');
t.start.next.next.follows.next.info();
t.start.info(1);
n1 = t.getNode(t.start, 'lottol');
if (n1 != None):
n1.info();
n1.info(1);
else:
print('无该节点');
t.dict();
print('banana'+'$' in t);
print('how'+'$' in t);
#计时结束
endTime = time.clock();
#打印结果
print('操作用时:{0:.3e} s'.format(endTime-startTime));
</span>但是有一点可以肯定,用递归可以把整个字典连成一棵树,而列表做不到。
即将奥运会了,阿伟决定好好地去研究一下奥运会,另外,最近也出了不少好看的电视剧,
也要抽点时间去看看。
本节到此结束,欲知后事如何,请看下回分解。
[从头学数学] 第255节 Python实现数据结构:字典树(Trie)
标签:
原文地址:http://blog.csdn.net/mwsister/article/details/52100592