7-44 基于词频的文件相似度 (30分)-set

实现一种简单原始的文件相似度计算,即以两文件的公共词汇占总词汇的比例来定义相似度。为简化问题,这里不考虑中文(因为分词太难了),只考虑长度不小于3、且不超过10的英文单词,长度超过10的只考虑前10个字母。

输入格式:

输入首先给出正整数N(≤100),为文件总数。随后按以下格式给出每个文件的内容:首先给出文件正文,最后在一行中只给出一个字符#,表示文件结束。在N个文件内容结束之后,给出查询总数M(≤10​4​​),随后M行,每行给出一对文件编号,其间以空格分隔。这里假设文件按给出的顺序从1到N编号。

输出格式:

针对每一条查询,在一行中输出两文件的相似度,即两文件的公共词汇量占两文件总词汇量的百分比,精确到小数点后1位。注意这里的一个“单词”只包括仅由英文字母组成的、长度不小于3、且不超过10的英文单词,长度超过10的只考虑前10个字母。单词间以任何非英文字母隔开。另外,大小写不同的同一单词被认为是相同的单词,例如“You”和“you”是同一个单词。

输入样例:

3
Aaa Bbb Ccc
#
Bbb Ccc Ddd
#
Aaa2 ccc Eee
is at Ddd@Fff
#
2
1 2
1 3

输出样例:

50.0%
33.3%

解题思路:

  1. 构建set数组,用于存储每个文件的词汇。
  2. 每次读取一行字符串,并通过deal()函数对字符串进行处理,每个字符串末尾加上'.',以便最后一个单词的读取。
  3. deal遍历读取字符串每一个元素,如果遇到字母字符,将其添加至word中;如果遇到非字符元素,判断word中字符数量,若满足条件,将其加入对应的set容器中。
  4. 根据编号遍历两个容器,统计两个容器中相同的元素个数,输出相似度。

代码如下:

#include <iostream>
#include <set>
#include <string>
using namespace std;
#define Max 100
void deal(string a,int num);
set<string> file[Max];
int main(){
	int i,n;
	cin>>n;
	getchar();
	for(i=0;i<n;i++){
		string word;
		getline(cin,word);
		while(word!="#"){
			deal(word,i);
			getline(cin,word);
		}	
	}
	int a1,a2;
	cin>>n;
	for(i=0;i<n;i++){
		cin>>a1>>a2;
		a1--;a2--;
		int cnt=0;
		int total=file[a1].size()+file[a2].size();
		set<string>::iterator it;
		for(it=file[a1].begin();it!=file[a1].end();it++){
			if(file[a2].find(*it)!=file[a2].end())
				cnt++;		
		}
		printf("%0.1f%\n",100.0*cnt/(total-cnt));
		
	}
	return 0;
	
}
void deal(string a,int num){
	string word;
	a+='.';
	int i;
	for(i=0;i<a.size();i++){
		if(isalpha(a[i])){
			if(word.size()<10)
				word+=tolower(a[i]);
		}
		else {
			if(word.size()>2){
				file[num].insert(word);
			}
				word.clear();	
		}
	}
	
}

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值