python实现字典树的插入、查找功能并基于pickle模块持久化存储字典树

来源:互联网 发布:czur scanner软件 编辑:程序博客网 时间:2024/06/07 01:29

    字典树是一个很有意思的东西,一直想用用试试,最早接触的时候也是在学长讲的时候了解到了这么一个东西,今天想起来了就实现了一下,很简单,因为我只是需要插入和查找这么两个功能用于后续的工作,对于字典树的介绍我就不多说了因为网上的教程讲解什么也都很多,在这里作为一个探索学习的记录就贴一下具体的一些介绍和性质,均来源于网上,如下:

    字典树(Trie)可以保存一些字符串->值的对应关系。基本上,它跟 Java 的 HashMap 功能相同,都是 key-value 映射,只不过 Trie 的 key 只能是字符串。Trie 的强大之处就在于它的时间复杂度。它的插入和查询时间复杂度都为 O(k) ,其中 k 为 key 的长度,与 Trie 中保存了多少个元素无关。Hash 表号称是 O(1) 的,但在计算 hash 的时候就肯定会是 O(k) ,而且还有碰撞之类的问题;Trie 的缺点是空间消耗很高。至于Trie树的实现,可以用数组,也可以用指针动态分配,我做题时为了方便就用了数组,静态分配空间。
Trie树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。Trie树中每个单词都是通过character by character方法进行存储,相同前缀单词共享前缀节点.Python没有指针,但是可以用嵌套字典来实现树结构.对于非ascii的单词,统一用unicode编码来插入与搜索。


Trie树的基本性质可以归纳为: 
(1)根节点不包含字符,除根节点意外每个节点只包含一个字符。
(2)从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。 
(3)每个节点的所有子节点包含的字符串不相同。


    好了,关于字典树的介绍和性质就说这么多,下面简单介绍下pickle模块的用法,pickle模块实现了基本的数据序列和反序列化。通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储;通过pickle模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象,在数据挖掘中经常会用到这个模块原因就是很多工作离不开机器学习的模型,很多模型的训练是极为消耗时间的,这里就需要将模型序列化存储在磁盘中,在需要利用模型来分类或者预测之类的工作的时候可以使用load函数,将之前保存磁盘的模型反序列化进入内存可以直接使用。

    pickle有两个版本一个是cPickle,另一个是pickle,前者是C语言版本的速度很快,后者是python语言版本的,都兼容,一般在使用的时候都会这么使用:

    import cPickle as pickle

序列化操作的基本方法为:

pickle.dump(model, model_file)

其中,model是待保存下来的模型的名称,model_file是已经打开的需要将model写入的文件的名称

反序列化操作的基本方法为:

pickle.load(model_file)

其中,model_file是保存model的文件

   这里,只是需要用到这两个功能,其他的还有很多功能和使用方法,在本文最后会给出参考教程链接

下面看具体的实现:

#!usr/bin/env python#encoding:utf-8'''__Author__:yishuihancheng功能:python实现在字典树,并持久化存储'''import cPickle as pickleclass TrieNode:    def __init__(self):        '''        定义节点的数据结构,并初始化,设置标志位判断是否单词是否是完整的存在于字典树中        '''        self.data={}        self.flag=Falseclass TrieTree(object):    def __init__(self):        '''        定义字典树的数据结构并初始化根节点        '''        self.root=TrieNode()    def insert_func(self, data):        '''        字典树的插入函数,data为待插入的数据,类型为字符串        '''        top_node=self.root        for i in range(len(data)):            one_char=data[i]            child_node=top_node.data.get(one_char)            if not child_node:                top_node.data[one_char]=TrieNode()            top_node=top_node.data[one_char]        top_node.flag=True    def search_func(self, data):        '''        字典树的查找函数,data类型为字符串        '''        top_node=self.root        for i in range(len(data)):            one_char=data[i]            top_node=top_node.data.get(one_char)            if not top_node:                return False        return top_node.flagif __name__ == '__main__':    str_list=['html','head','body','meta','div','link','a','comment','iframe','ul','li']    search_list=['html','table','body','tr','h1','script','javascript','iframe']    TestTrieTree=TrieTree()    for one_str in str_list:        TestTrieTree.insert_func(one_str)    print '***********************************结果如下,True表示存在,False表示不存在******************************************'    for one_str in search_list:        print one_str,   TestTrieTree.search_func(one_str)    print '----------------------------------持久化存储TestTrieTree模型---------------------------------'    trie_file=file('trie.pkl', 'w')    pickle.dump(TestTrieTree, trie_file)    trie_file=open('trie.pkl')    trie_model=pickle.load(trie_file)    print trie_model.insert_func('yi')    print trie_model.insert_func('shui')    print trie_model.insert_func('han')    print trie_model.insert_func('cheng')    print '-------------------insert over----------------------------'    print trie_model.search_func('yi')    print trie_model.search_func('shui')    print trie_model.search_func('han')    print trie_model.search_func('cheng')    print '-------------------search over----------------------------'

下面看结果:


     很简单的小实验,主要是想学习一下字典树,因为之后的话想着考虑将这个工具加入到项目中,实现快速的检索的目的,这个甚至真的可以取代hash来作为索引,毕竟,现在的目的是减少时间的消耗,对于存储空间并不是很在意。

参考链接:

http://blog.sina.com.cn/s/blog_3fe961ae0101j4pa.html

http://blog.csdn.net/lxg0807/article/details/71082408

http://www.cnblogs.com/cobbliu/archive/2012/09/04/2670178.html

阅读全文
0 0
原创粉丝点击