基于 double array 实现汉字的trie树索引 与 查询功能 python实现
2012-04-08 21:05
1196 查看
一、 基本原理。
基本原理:利用字符串集合中字符串的公共前缀来降低时间开销以达到提高效率的目的。
性质:1,根结点不包含任何字符信息;2,如果字符的种数为n(如英文的26个字母),则每个结点的出度为n(这样必然会导致浪费很多空间,这也是trie的缺点,我还没有想到好点的办法避免);3,查找,插入复杂度为O(n),n为字符串长度。
具体请百度之。
二、基于 trie字典的汉字串检索代码(python):
基本原理:利用字符串集合中字符串的公共前缀来降低时间开销以达到提高效率的目的。
性质:1,根结点不包含任何字符信息;2,如果字符的种数为n(如英文的26个字母),则每个结点的出度为n(这样必然会导致浪费很多空间,这也是trie的缺点,我还没有想到好点的办法避免);3,查找,插入复杂度为O(n),n为字符串长度。
具体请百度之。
二、基于 trie字典的汉字串检索代码(python):
# coding=gbk dicts = ['啊','阿根廷','阿胶','阿拉伯','阿拉伯人','埃及'] # 字后缀数组 sufarr = {'啊':[],'阿':['根','胶','拉'],'埃':['及'], '根':['廷'],'胶':[],'拉':['伯'],'及':[], '廷':[],'伯':['人'],'人':[]} # 按ID编码 codes = [ '啊','阿','埃','根','胶','拉','及','廷','伯','人' ] # 字的层次标示 level = [1, 1, 1, 2, 2, 2, 2, 3, 3, 4] # 构建双数组 base = [0]*21 # len:21 ; 21=2*10+1 的素数 check = [0]*21 # 记录已确定的字的base索引 bid_mark = {'啊':0,'阿':1,'埃':2, '根':0,'胶':0,'拉':0,'及':0,'廷':0,'伯':0,'人':0} base[:3]=[1]*3 # 首字部分,简单置为1 def pre_mark(pre_word,wi,word): ''' 判断base中wi下标的前缀都在pre_words词表直到首字 且word为wi下标对应的字 ''' bkeys = bid_mark.keys() if word not in bkeys or bid_mark[word]!=wi: # 当前字的base值不匹配 return False pre_wi = check[wi] # 逆序遍历base的前缀 pid = -1 # 逆序遍历字的前缀 while pre_wi!=0 and (-1)*pid<=len(pre_word): if pre_word[pid] not in bkeys or bid_mark[pre_word[pid]]!=pre_wi: return False pre_wi = check[pre_wi] pid -= 1 if (-1)*pid>len(pre_word): return True # 完成前缀的遍历 else: return False for w in dicts: cw = [ w[i:i+2] for i in range(0,len(w),2) ] # 分割出字 for iid in range(1,len(cw)): par_w = cw[iid-1] # 字的前缀 iid_w = cw[iid] # 当前的字 par_id = codes.index(par_w) # 字的前缀的编码 wid = codes.index(iid_w) bval = bid_mark[par_w] #if iid_w=='及': print "ID: %d, word: %s, pre-wrod: %s, code: %d, pre-code: %d, pre-base:%d"%( # iid,iid_w,par_w,wid,par_id,bval) for wi in range(base[bval]+wid,21): # 遍历所有可能的base位置 # 找到其base-id,置位 p_mk = pre_mark(cw[:iid],wi,iid_w) print "TEST::pre_mark() base-id: %d, word: %s, result: %s"%(wi,iid_w,str(p_mk)) if p_mk: # 该词及其前缀部分已经设置值 break if (not base[wi] and not check[wi]): # 该位置未使用或吻合前缀 check[wi] = bval # 设置字的 base[] 值 for tval in range(1,21-wi): # 遍历所有可能的取值 flag = True for suf_w in sufarr[iid_w]: chi_id = codes.index(suf_w) # 字的后缀的编码 if base[tval+chi_id]!=0 or check[tval+chi_id]!=0: flag = False break # tval不满足child的base check 为0,再尝试其他值 if flag: base[wi] = tval # 成功,保存该base[] if wi==6 or wi==-1 or wi==9: print "ID: %d, word: %s, pre-word: %s, base: %d, base-val: %d, check: %d"%( iid,iid_w,par_w,wi,tval,check[wi]) break if not base[wi]: # 无合适的 base print "ERROR:: set %s's base[]" % iid_w exit(1) bid_mark[iid_w] = wi #; print "finnished one! %s=%d" % (iid_w,wi) break # base check均成功 if not base[wi]: print "ERROR:: get %s's position in base[]" % iid_w exit(2) # 修改词尾标志 for w in bid_mark.keys(): if len(sufarr[w])==0: eid = bid_mark[w] base[eid] *= -1 # 查询给定词 def next_check(wid, code): ''' 验证两个base[]索引id间是否有连接 ''' if code<0 or code>=len(codes): # 字编码无效 return False chiid = abs(base[wid])+code if check[chiid]!=wid: return False return True qw = dicts[1] ; # 查询词 res = '' # 返回结果 words=[ qw[w:w+2] for w in range(0,len(qw),2) ] head_bid = bid_mark[words[0]] ; res = ''.join(words[0]) for w in words[1:]: cod = codes.index(w) if not next_check(head_bid,cod): print "word: %s no find!" % qw break head_bid = abs(base[head_bid])+cod # 更新id res = ''.join([res,w]) if base[head_bid]<0: print "find a word: %s in Search word: %s"%(res,qw)参考: http://blog.csdn.net/joylnwang/article/details/6825991
相关文章推荐
- Python+Socket实现基于TCP协议的客户与服务端中文自动回复聊天功能示例
- 利用JQuery方便实现基于Ajax的数据查询、排序和分页功能
- Python实现的手机号归属地相关信息查询功能示例
- Python基于TCP实现会聊天的小机器人功能示例
- Python实现的拟合二元一次函数功能示例【基于scipy模块】
- Python实现Sqlite将字段当做索引进行查询的方法
- 利用JQuery方便实现基于Ajax的数据查询、排序和分页功能
- Python基于PyGraphics包实现图片截取功能的方法
- 【lucene系列学习一】实现Lucene索引,查询以及中文分词功能
- Python实现SQL查询功能示例
- Python使用文件锁实现进程间同步功能【基于fcntl模块】
- 一个基于thinkphp 的 easyui datagrid 组件查询功能的实现
- Python实现基于PIL和tesseract的验证码识别功能示例
- 基于bootstrap-select插件,实现select下拉框模糊查询功能
- 基于Python的电子教室软件中远程关机功能的原理与实现
- Python基于matplotlib实现绘制三维图形功能示例
- Android实战简易教程<二十四>(基于Baas的用户表查询功能实现!)
- Python基于SMTP协议实现发送邮件功能详解
- Python基于list的append和pop方法实现堆栈与队列功能示例
- Python实现基于C/S架构的聊天室功能详解