学习信息检索课程,老师让写一个倒排索引与查询处理的程序,于是抱着试试的心态自学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