/*5. 倒排文档
[问题描述]
倒排索引是搜索引擎中一个很基本的概念,几乎所有的搜索引擎都会使用到倒排索引。简单地说,倒排索引就是将文件中的单词作为关键字,然后建立单词与文件的映射关系,同时还需要记录文件中单词出现的频数等信息。
建立倒排索引的过程,需要对文件进行顺序的扫描,在这个过程中,我们一般还会统计一下词的分布情况,比如想知道频次排名第X的词(如果两个词的词频相同,则按照字母顺序排序)会出现多少次? 为方便实现,首先以简单的键盘输入形式逐行输入文件的内容,实现基本的功能之后,再将输入方式改成从文本文件中读取。
例如:输入
第一行需要查询的单词W
第二行文本的总行数N
第三行频次排名R
剩下为文本(每个单词之间靠空格隔开)
输出
第一行输出该词所在的行数序号(多个的话,按照从小到大排序输出,中间空格隔开,序号从一开始记),如果没有出现,输出 -1
第二行输出频次排名R的单词出现的次数。
[测试数据]
输入为:I
4
3
I am a student .
I live in Beijing and I love Bejing
I also love travelling, life in there
Beijing is beautiful
输出为:
1 2 3
2
[实现提示]
可以用如下格式作为输入输出形式:
输入
第一行需要查询的单词W
第二行文本的总行数N
第三行频次排名R
剩下为文本(每个单词之间靠空格隔开)
输出
第一行输出该词所在的行数序号(多个的话,按照从小到大排序输出,中间空格隔开,序号从一开始记),如果没有出现,输出 -1
第二行输出频次排名R的单词出现的次数。
测试数据中的词频的分布如下,可见,排名第3的词,出现的次数为2
I,4
Beijing,2
in,2
love,2
.,1
Bejing,1
a,1
also,1
am,1
and,1
beautiful,1
is,1
life,1
live,1
student,1
there,1
travelling,1
*/
#include<iostream>
using namespace std;
void match(char text[][500],char input[],int &m,int n)
{
int flag;
for(int i=0;i<n;i++)
{
flag=0;
for(int j=0;j<strlen(text[i]);j++)
{
int p=1;
for(int k=0;k<strlen(input);k++)
{
if(input[k]!=text[i][j+k])
{
p=0;
break;
}
}
if(p)
{
m++;
if(flag==0)
{
cout<<"The word at Row : "<<i+1<<endl;
flag=1;
}
}
}
}
cout<<endl;
}
void howmanywords(char text[][500],char words[][30],int n,int &w)
{
int k=0,b;
for(int i=0;i<n;i++)
{
for(int j=0;j<strlen(text[i]);j++)
{
if((text[i][j]<='z'&&text[i][j]>='a')||(text[i][j]<='Z'&&text[i][j]>='A'))
{
k++;//k作为标记,若k>0,代表有英文字母出现过.
}
else//text[i][j]不是英文字母,
{
if(k>0)//并且有英文字母出现过,那么前面出现过的英文合起来,就算是一个单词
{
for(b=0;k>0;k--,b++)
{
words[w][b]=text[i][j-k];
}
w++;
}
k=0;
}
if(k>0&&j==strlen(text[i])-1)//这里用来将英文字母合并成单词
{
for(b=0;k>0;k--,b++)
{
words[w][b]=text[i][j-k+1];
}
w++;
}
}
k=0;
}
}
void wordscount(char words[][30],int w,int &m1)
{
for(int i=0;i<w;i++)
for(int j=i+1;j<w;j++)
{
if(!strcmp(words[i],words[j]))
m1++;
}
}
void count(char words[][30],int w,int a[],int &p)
{
for(int i=0;i<w;i++)
{
a[i]=1;
for(int j=i+1;j<w;j++)
{
if(!strcmp(words[i],words[j]))
{
for(int k=j;k<w;k++)
{
strcpy(words[k],words[k+1]);
}
w--;
a[i]++;
j--;
}
}
p++;
}
}
void sort(int a[],int b[],char words[][30],int p)
{
int t;
char c[30];
for(int q=0;q<p;q++)
b[q]=a[q];
for(int j=0;j<p-1;j++)//这里运用冒泡法,按出现频率降序,排单词顺序,对应的,I 出现4次,排名第一,对应的b[0]也就=4.单词beijing出现2次,排名第二,对应的b[1]=2.
{
for(int i=0;i<p-j-1;i++)
if(b[i]<b[i+1])
{
t=b[i+1];
b[i+1]=b[i];
b[i]=t;
strcpy(c,words[i+1]);
strcpy(words[i+1],words[i]);
strcpy(words[i],c);
}
}
}
void main()
{
FILE *fp;
char text[100][500],input[30],words[500][30]={0};
int n2,n1,n,r,m=0,w=0,m1=0,a[100]={0},b[100]={0},p=0,i;
fp=fopen("f:\\1.txt","r");
cout<<"Please input the word u wanna input."<<endl;
cin>>input;//input代表你想输入的单词
cout<<"How many rows?"<<endl;
cin>>n1;//n1代表你想输入的行数或读取文件中信息的行数.
n=n1+1;
cout<<"The Rank:"<<endl;
cin>>r;
cout<<"If u wanna input some text please input 1;"<<endl;//若想自己输入句子,选1
cout<<"If u wanna read a file please input 2(Path: f:\\ 1.txt );"<<endl;//若要从文件获取句子选2.
cin>>n2;//输入1,或2,我没写异常.
if(n2==1)
{
cout<<"Now,show me ur text(Please ignore Row 0 )"<<endl;//程序会多余输出一个row0,请无视他.
for(int i=0;i<n;i++)
{
cout<<"Row :"<<i<<endl;
gets(text[i]);//text用于用户存放输入的句子
}
cout<<endl;
}
else if(n2==2)
{
for(i=0;i<n;i++)
fgets(text[i],strlen(text[i]),fp);
strcpy(text[--i],"");
cout<<"This is the file:"<<endl;
for(i=0;i<n;i++)
cout<<text[i]<<endl;
}
howmanywords(text,words,n,w);//计数,记下文本中有多少个单词.
match(text,input,m,n);//用于匹配用户输入的词在文本中是否存在,存在在那里.
cout<<endl<<"The word occure "<<m<<" times"<<endl;//m代表用户输入的词出现在文中的次数.
cout<<"Total words: "<<w<<endl;//w代表文本总词数
wordscount(words,w,m1);//计算文本中有多少相同的词.
cout<<"The Same word:"<<m1<<endl;//m1代表相同词的个数
count(words,w,a,p);//这个函数是用来计算每个单词在文中重复出现的次数
sort(a,b,words,p);//这是寻找用户输入的频次排名r的词出现了多少次.
cout<<endl;
cout<<endl;
if(b[r-1]!=1)
cout<<"Rank "<<r<<" occure "<<b[r-1]<<" times."<<endl;
else
cout<<"Rank "<<r<<" occure "<<b[r-1]<<" time."<<endl;
fclose(fp);
}
软件实习-倒排文档
最新推荐文章于 2020-05-18 14:59:13 发布