PTA 7-44 基于词频的文件相似度 (30 point(s))

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

输入格式:

输入首先给出正整数N(≤100),为文件总数。随后按以下格式给出每个文件的内容:首先给出文件正文,最后在一行中只给出一个字符#,表示文件结束。在N个文件内容结束之后,给出查询总数M(≤104),随后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%

结尾无空行

#include <bits/stdc++.h>
using namespace std;

int N, M, a, b, same[101][101];
map<string, int> file[101];
string word;
char c;

main() {
	cin >> N;
	for (int i = 1; i <= N; ++i) {
		while ((c = tolower(getchar())) != '#'){
            // 如果字符是字母 且字符串不超过10位
            if (isalpha(c)) {
                // 有容量时加入字符
				if (word.size() < 10)
					word += c;
			}
            // 非字母时重置字符串 并判断是否时单词
			else {
                // 字符串大于等于3成为一个单词
				if (word.size() > 2)
					file[i][word] = 1;
				word.clear();
			}
        }
        // 统计共同词汇
		for (auto it : file[i]){
            // 遍历其他文件名j(当前文件名编号i)
            for (int j = 1; j <= i; j++){
                //如果找到单词 累计两者的共同词汇
                if (file[j].find(it.first) != file[j].end())
                    same[i][j] = same[j][i] += 1;
            }
        }
	}
	cin >> M;
	while(M--) {
		cin >> a >> b;
		cout << fixed << setprecision(1) << 100.0 * same[a][b] / (file[a].size() + file[b].size() - same[a][b]) << "%" << endl;
	}
}

if (isalpha(s)) {
                if (word.size() < 10)
                    word += s;
}

 当字符为字母时,字符串未到上限则累加,如果超过上限而后面仍然是字母则会继续读取但不会累加。比如“ABCDEFGHIJKLMN”,上限读取到'J',后面仍然是字母,只会读取但不累加。

else {
                if (word.size() > 2)
                    file[i][word] = 1;
                word.clear();

 判断非字母时,比如样例里如果有一字符串为 “Ddd@Fff ”那么前面的Ddd会成为一个单词并统计。因为当前尚未到'#',故Fff会继续读取并遇到空格成为下一个单词。

file[i][word] = 1;

记录单词时赋值为1,而不是++累加。题目问词频意味不同词汇,而不是同样词汇出现的次数。 

参考代码

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值