倒排索引原理:根据属性的值来查找记录位置。
假设有3篇文章,file1, file2, file3,文件内容如下:
file1 (单词1,单词2,单词3,单词4....)
file2 (单词a,单词b,单词c,单词d....)
单词1 (file1,file3)
单词2 (file1)
单词3 (file1,file3)
单词a (file2, file3)
假设有3篇文章,file1, file2, file3,文件内容如下:
file1 (单词1,单词2,单词3,单词4....)
file2 (单词a,单词b,单词c,单词d....)
file3 (单词1,单词a,单词3,单词d....)
单词1 (file1,file3)
单词2 (file1)
单词3 (file1,file3)
单词a (file2, file3)
...
下面是我对于倒排索引的一个简单的实现。该程序实现了某目录下的文件单词统计,并建立了倒排索引。
头文件:inverted_index.h
#define MAXLINE 1024
class InvertedIndex
{
public:
InvertedIndex(){}
~InvertedIndex(){result_index_.clear();}
int StatWords(const char* file_name);
map<string,map<string,int> > result_index(){return result_index_;}
private:
//存放倒排索引结果,key是单词,value也是map,该map的key是文件名,value是该单词在该文件中出现的次数
map<string,map<string,int> > result_index_;
int ParseWordsByLine(char* str_line, const char* file_name);
void InsertWordToMap(char* word, const char* file_name);
};
实现文件:inverted_index.cpp
int InvertedIndex::StatWords(const char* file_name)
{
FILE *fp;
if((fp = fopen(file_name,"r")) == NULL)
{
printf("cannot open %s", file_name);
return -1;
}
char str_line[MAXLINE];
while(fgets(str_line, MAXLINE, fp) != NULL)
{
int len = strlen(str_line);
str_line[len-1] = '\0'; /*去掉换行符*/
ParseWordsByLine(str_line,file_name);
}
fclose(fp);
return 0;
}
int InvertedIndex::ParseWordsByLine(char* str_line, const char* file_name)
{
if(strlen(str_line) == 0)
{
return -1;
}
const char* needle=" \n\t";
/*strtok在s中查找包含在delim中的字符并用NULL(‘\0’)来替换,直到找遍整个字符串。
返回值:从s开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。*/
char* word = strtok(str_line, needle);
while(word != NULL)
{
InsertWordToMap(word,file_name);
word = strtok(NULL, needle);
}
return 0;
}
void InvertedIndex::InsertWordToMap(char* word, const char* file_name)
{
if(strlen(word) == 0)
{
return;
}
string word_str = word;
string file_name_str = file_name;
map<string,map<string,int> >::iterator it;
it = result_index_.find(word_str);
if(it == result_index_.end())//not found
{
map<string,int> file_word_count;
file_word_count.insert(pair<string,int>(file_name_str,1));
result_index_[word_str] = file_word_count;
}
else
{
map<string,int> file_word_count = result_index_[word_str];
file_word_count[file_name_str] ++ ;
result_index_[word_str] = file_word_count;
}
}
运行结果:
全部源代码:https://github.com/zhihaibang/benson-style/tree/master/C%2B%2B/inverted_index