一. 实验目的
1.掌握列表、集合和字典的定义、赋值、使用等基本操作,熟悉处理复杂数据类型的一般流程
2.熟悉列表、集合和字典的常用函数和技巧
3.考察对文本的灵活处理和对排序算法的运用
二. 实验内容
倒排索引(Inverted index),也常被称为反向索引,是一种索引方法,用来存储某个单词存在于哪些文本之中。是信息检索系统中最常用的数据结构。通过倒排索引,可以根据单词快速获取包含这个单词的文档列表。
本实验主要完成以下三个功能:
(1). 建立索引:首先输入100行字符串,用于构建倒排索引,每行字符串由若干不含标点符号的、全部小写字母组成的单词构成,每个单词之间以空格分隔。依次读入每个单词,并组成一个由<单词, 每个单词出现的行号集合>构成的字典,其中行号从1开始计数。
(2). 打印索引:按照字母表顺序依次输出每个单词及其出现的位置,每个单词出现的位置则按行号升序输出。例如,如果“created”出现在第3, 20行,“dead”分别出现在14, 20, 22行。则输出结果如下(冒号和逗号后面都有一个空格,行号不重复):
…
created: 3, 20
dead: 14, 20, 22
…
(3). 检索:接下来输入查询(Query)字符串,每行包含一个查询,每个查询由若干关键字(Keywords)组成,每个关键字用空格分隔且全部为小写字母单词。要求输出包含全部单词行的行号(升序排列),每个查询输出一行。若某一关键字在全部行中从没出现过或没有一行字符串包含全部关键字,则输出“None”。遇到空行表示查询输入结束。如对于上面创建的索引,当查询为“created”时,输出为“3, 20”;当查询为“created dead”时,输出为“20”;当查询为“abcde dead”时,输出为“None”;
(4). 高级检索:当输入的Query以“AND:”开始,则执行“与”检索,即要求输出包含全部关键字的行;如果输入的Query以“OR:”开始,则执行“或”检索,即某行只要出现了一个关键字就满足条件。默认情况(不以“AND:”或“OR:”开始),执行“与”检索。
解题思路
题目的意思和主要完成的思路已经讲的很明白了:就是先给你100行句子建个字典,然后打印字典,最后查字典。查字典工作包括两种查法:AND查询和OR查询,AND查询操作其实就是集合的交,OR查询就是集合的并。题目里的“(3).检索”就是AND查询。
具体实现及出现问题
建立字典:我使用的是字典这种存储结构,我用前100行中所有单词作为key,values则是一个存储每个单词出现行数的集合
打印字典:因为要输出符合字典序的字典,所以要用到python自带的排序函数,注意排序的结果是个list(索引值是key,索引结果是set的列表形式),然后就可以愉快的打印了
查询:AND查询是集合的交,OR查询是集合的并。所以我建字典的时候很机智的用了set作为values。
边界情况:查询的时候有空格行;
出现过的问题:
对字典进行排序之后,默认把所有set,dictionary……都变成list。
s = ‘空格’ s.split()的结果是[空] s.spilt(空格)的结果是[空格,空格]
代码:
# -*- coding: utf-8 -*-
"""
Created on Sat Nov 22 09:57:06 2014
@author: Liyu Fu
"""
'''Step one:New Dictionary'''
dict1 = {}
for i in range(100):
sentence = raw_input()
word_list = sentence.split()
for word in word_list:
if word not in dict1:
dict1[word] = set() #new word
dict1[word].add(i+1) #update for dictionary
'''Step two:Print Index'''
answer_list = sorted(dict1.iteritems(),key=lambda d:d[0])#Sort by keyword of dictionary.
for word in answer_list:
l = list(word[1])
l.sort()
print word[0]+': '+', '.join(map(str,l)) #Print Index
def print_answer(answer_set): #Output search results
empty_set = set()
if empty_set == answer_set: #answer_set is empty
print 'None'
else:
answer_list=list(answer_set)
answer_list.sort()
print ', '.join(map(str,answer_list)) #Print answer of Query
'''Step three:Retrieval'''
while True:
Query = raw_input()
if Query == '': break #Exit condition
answer_set = set()
if 'OR:' in Query: #OR-Retrieval
Query = Query[3:]
Q_word_list = Query.split()
for word in Q_word_list:
if (word != '')and(word in dict1):
answer_set = dict1[word]|answer_set #set or
print_answer(answer_set)
else: #AND-Retrieval
if 'AND:' in Query:Query = Query[4:]
Q_word_list = Query.split()
if Q_word_list!=[]:
for i in range(1,101):answer_set.add(i)
for word in Q_word_list:
if (word != ''):
if word in dict1:
answer_set = dict1[word]&answer_set #set and
else:answer_set = set() #wrong word
print_answer(answer_set)
else:print 'None'
转载自python倒排索引