软件实习-倒排文档

/*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);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值