学习信息检索课程,老师让写一个倒排索引与查询处理的程序,于是抱着试试的心态自学python写了出来。
整个没有什么太大的算法技巧,唯一的就是查询处理那里递归函数正反两次反复查找需要多调试下。
数据结构:
#-*-coding:utf-8-*- #!/usr/bin/python ''' 数据结构 建立索引 mydir 文档列表 onedoc 每一个文档 mydoc 当前查询的文档 mywords 建立索引的字典 myindex 0 文档下标 1 单词下标 2 次数 3... wordcntdict中的个数 doccnt文档个数 三个字典 mywordsdictindex 单词编号 起始位置 antimywordsdict 单词编号 结束位置 mywordsdict 单词->单词编号 查询 mypos是每个的单词起始的index下标 myfindindex是每个单词的标号, mydocs 查询到的文档号 ''' mydir=[] mywords=[] myindex=[] mywordsdictindex={} antimywordsdict={} mywordsdict={} wordcnt=0#dict中的个数 doccnt=0#文档个数 listcnt=0#index个数 mypos=[] mydocs=[] myfindindex=[] mydoc=0 direct=0 print id(mydir)
创建索引:
#-*-coding:utf-8-*- #!/usr/bin/python from mydate import * import sys import os import pprint import pickle def getmydoc(thepath,onedir): ans=[] for line in open(thepath+'/'+onedir): line=line.strip('\n') ans.append(line) return ans def createindex(thepath): global mydir global mywords global myindex global mywordsdictindex global antimywordsdict global mywordsdict global wordcnt global doccnt global listcnt global mypos global mydocs global myfindindex global mydoc global direct mydir=os.listdir(thepath) for i in mydir: if(os.path.isdir(thepath+'/'+i)==True): mydir.remove(i) #print mydir mydir=['a.txt','b.txt','c.txt'] wordcnt=0#dict中的个数 doccnt=0#文档个数 listcnt=0#index个数 print id(wordcnt) for onedoc in mydir: mylist=getmydoc(thepath,onedoc) onedocword=0#每个词在这个文本中的位置 docworddict={} for myword in mylist: if(myword not in mywordsdict): mywords.append([0]*2) mywords[wordcnt][0]=myword mywordsdict[myword]=wordcnt wordcnt+=1 #print myword,mywordsdict[myword] if(myword not in docworddict): docworddict[myword]=listcnt listcnt+=1 myindex.append([0]*3) ins=docworddict[myword] myindex[ins][0]=doccnt myindex[ins][1]=mywordsdict[myword] myindex[ins][2]+=1 myindex[ins].append(onedocword) onedocword+=1 doccnt+=1 myindex.sort(key=lambda x:x[1]) #sort beg=0 fin=0 for i in range(len(mywords)): mywordsdictindex[mywords[i][0]]=beg mywords[i][1]=beg while fin <len(myindex) and myindex[fin][1]==i:#python不支持逻辑短路 fin+=1 beg=fin for i in range(len(mywords)): mywordsdictindex[i]=mywords[i][1] if(i==len(mywords)-1): antimywordsdict[i]=len(myindex) else: antimywordsdict[i]=mywords[i+1][1] ''' pprint.pprint (mywords) pprint.pprint (myindex) pprint.pprint (mywordsdict) pprint.pprint (mywordsdictindex) pprint.pprint (antimywordsdict) out=open("myindex.dat","wb") pickle.dump(myindex,out) out=open("mywords.dat","wb") pickle.dump(mywords,out) '''
#-*-coding:utf-8-*- #!/usr/bin/python #得到一个文本的列表 import sys import os import pprint import pickle import pdb from mydate import * ''' 返回值三种:1 整个查询词都找到了 0 并没有同时出现在一个文本中 -1 查询完毕或不存在 mydoc 查询词是否都在这个文档中 direct 查询方向 direct=0 递归向下,携带标记flag若为1则表明之前一直存在。0表明并不都在一个文本中那么mydoc取过程中的最大值 当到len(mypos)的时候,决定是否将该结果放入,并将最后一个词的mypos后移 改变查询方向,并返回1 direct=1 递归返回,与0同样操作,当到第0层再改变查询方向 ''' def findword(loc,flag): global mydir global mywords global myindex global mywordsdictindex global antimywordsdict global mywordsdict global wordcnt global doccnt global listcnt global mypos global mydocs global myfindindex global mydoc global direct if(loc==len(mypos)): #pdb.set_trace() direct=1############################# if(flag==1): mydocs.append(mydoc) i=mypos[loc-1]+1 #print mydocs if(i<antimywordsdict[myfindindex[loc-1]]): mydoc=myindex[i][0] else: return -1 return 1 i=mypos[loc] while i<antimywordsdict[myfindindex[loc]]: if(flag==-1): return -1 if(loc==0 and direct==1): direct=0 if( flag==1 and loc==0): mydocs.append(mydoc)############################# i+=1 #print mydocs if(i<antimywordsdict[myfindindex[loc]]): mydoc=myindex[i][0] else: return 0 T=0 while i<antimywordsdict[myfindindex[loc]] and myindex[i][0]<=mydoc: if(myindex[i][0]==mydoc): T=1 break i+=1 if(T==0): if(i+1==antimywordsdict[myfindindex[loc]]): return -1 i+=1 mydoc=myindex[i][0] mypos[loc]=i############################# if(flag==1 and T==1): pass else: T=0 if(direct==1): return T flag=findword(loc+1,T) return 0 def getwords(): global mydir global mywords global myindex global mywordsdictindex global antimywordsdict global mywordsdict global wordcnt global doccnt global listcnt global mypos global mydocs global myfindindex global mydoc global direct searchword=raw_input("find words\n") searchword=searchword.split(' ') flag=True for i in range(len(searchword)): if(searchword[i] not in mywordsdict): flag=False break myfindindex.append(mywordsdict[searchword[i]])#mypos是每个的单词起始的index下标,myfindindex是每个单词的标号,三个字典 mypos.append(mywordsdictindex[searchword[i]]) if(flag==False): print 'wrong' sys.exit() mydoc=myindex[mywordsdictindex[myfindindex[0]]][0] direct=0 import pdb #pdb.set_trace() flag=findword(0,0) print mydocs#mydocs 查询到的文档号 返回这个数据
#-*-coding:utf-8-*- #!/usr/bin/python import hwf from mydate import * import createindex import sys import os import pprint import pickle createindex.createindex('.')#创建索引 hwf.getwords()#查询单词
原文地址:http://blog.csdn.net/gg_gogoing/article/details/40039131