CCF CSP 2024 3-1.2 词频统计 相似度计算 (全AC)

词频统计

题目描述

在学习了文本处理后,小 P 对英语书中的 nn 篇文章进行了初步整理。 具体来说,小 P 将所有的英文单词都转化为了整数编号。假设这 nn 篇文章中共出现了 mm 个不同的单词,则把它们从 11 到 mm 进行编号。 这样,每篇文章就简化为了一个整数序列,其中每个数都在 11 到 mm 范围内。

现给出小 P 处理后的 nn 篇文章,对于每个单词 ii(1≤i≤m1≤i≤m),试统计:

  1. 单词 ii 出现在了多少篇文章中?
  2. 单词 ii 在全部文章中总共出现了几次?

输入格式

从标准输入读入数据。

输入共 n+1n+1 行。

输入的第一行包含两个正整数 nn 和 mm,分别表示文章篇数和单词编号上限。

输入的第 i+1i+1 行(1≤i≤n1≤i≤n)包含由空格分隔的若干整数, 其中第一个整数 lili​ 表示第 ii 篇文章的长度(单词个数); 接下来 lili​ 个整数表示对应的整数序列,序列中每个整数均在 11 到 mm 范围内,各对应原文中的一个单词。

输出格式

输出到标准输出。

输出共 mm 行。

第 ii 行(1≤i≤m1≤i≤m)输出由空格分隔的两个整数 xixi​ 和 yiyi​,表示共有 xixi​ 篇文章包含单词 ii,总计出现次数为 yiyi​。

样例输入

4 3
5 1 2 3 2 1
1 1
3 2 2 2
2 3 2

样例输出

2 3
3 6
2 2

样例解释

单词 22 在:

  • 文章 11 中出现两次;
  • 文章 33 中出现三次;
  • 文章 44 中出现一次。

因此 x2=3x2​=3、y2=6y2​=6。

子任务

全部的测试数据满足 0<n,m≤1000<n,m≤100,且每篇文章至少包含一个单词、最多不超过 100100 个单词(1≤li≤1001≤li​≤100)。

代码

普通的二维数组

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

int wenzhang[100][100];
//int quanbu[100];

int main(){
	int n,m;
	cin>>n>>m;
	int chuxian[101]={0};
	
int l[100];
	//int cnt=0;
	for(int i=0;i<n;i++){
	cin>>l[i];
	for(int j=0;j<l[i];j++){
		cin>>wenzhang[i][j];
//		quanbu[cnt]=wenzhang[i][j];
//		cnt++;
		chuxian[wenzhang[i][j]]++;
		
	}
		
	}
	for(int x=1;x<=m;x++){
		int sum=0;
		for(int i=0;i<n;i++){
			for(int j=0;j<l[i];j++){
		if(x==wenzhang[i][j]){
			sum++;
			break;
		}
			}
		}
		cout << sum<<" "<< chuxian[x]<< endl;
		
		
	}
	
	
}

相似度计算

题目背景

两个集合的 Jaccard 相似度定义为:Sim(A,B)=∣A∩B∣∣A∪B∣Sim(A,B)=∣A∪B∣∣A∩B∣​即交集的大小除以并集的大小。当集合 AA 和 BB 完全相同时,Sim(A,B)=1Sim(A,B)=1 取得最大值;当二者交集为空时,Sim(A,B)=0Sim(A,B)=0 取得最小值。

题目描述

除了进行简单的词频统计,小 P 还希望使用 Jaccard 相似度来评估两篇文章的相似性。 具体来说,每篇文章均由若干个英文单词组成,且英文单词仅包含“大小写英文字母”。 对于给定的两篇文章,小 P 首先需要提取出两者的单词集合 AA 和 BB,即去掉各自重复的单词。 然后计算出:

  • ∣A∩B∣∣A∩B∣,即有多少个不同的单词同时出现在两篇文章中;
  • ∣A∪B∣∣A∪B∣,即两篇文章一共包含了多少个不同的单词。

最后再将两者相除即可算出相似度。 需要注意,在整个计算过程中应当忽略英文字母大小写的区别,比如 theThe 和 THE 三者都应被视作同一个单词。

试编写程序帮助小 P 完成前两步,计算出 ∣A∩B∣∣A∩B∣ 和 ∣A∪B∣∣A∪B∣;小 P 将亲自完成最后一步的除法运算。

输入格式

从标准输入读入数据。

输入共三行。

输入的第一行包含两个正整数 nn 和 mm,分别表示两篇文章的单词个数。

第二行包含空格分隔的 nn 个单词,表示第一篇文章;

第三行包含空格分隔的 mm 个单词,表示第二篇文章。

输出格式

输出到标准输出。

输出共两行。

第一行输出一个整数 ∣A∩B∣∣A∩B∣,即有多少个不同的单词同时出现在两篇文章中;

第二行输出一个整数 ∣A∪B∣∣A∪B∣,即两篇文章一共包含了多少个不同的单词。

样例1输入

3 2
The tHe thE
the THE

样例1输出

1
1

样例1解释

A=B=A∩B=A∪B=A=B=A∩B=A∪B= {the}

样例2输入

9 7
Par les soirs bleus dete jirai dans les sentiers
PICOTE PAR LES BLES FOULER LHERBE MENUE

样例2输出

2
13

样例2解释

A=A= {bleus, dans, dete, jirai, les, par, sentiers, soirs} ∣A∣=8∣A∣=8

B=B= {bles, fouler, les, lherbe, menue, par, picote} ∣B∣=7∣B∣=7

A∩B=A∩B= {les, par} ∣A∩B∣=2∣A∩B∣=2

样例3输入

15 15
Thou that art now the worlds fresh ornament And only herald to the gaudy spring
Shall I compare thee to a summers day Thou art more lovely and more temperate

样例3输出

4
24

子任务

80%80% 的测试数据满足:n,m≤100n,m≤100 且所有字母均为小写;

全部的测试数据满足:n,m≤104n,m≤104 且每个单词最多包含 1010 个字母。

代码

主要是对哈希表的使用

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


int main(){
	
	int n,m;
	cin>>n>>m;
	string s;
	int j=0;
//注意这里哈希表的运用
	unordered_map<string,int> jiaoji;  
	for(int i=0;i<n;i++){
		cin>>s;
		for(int j=0;j<s.size();j++){
			if(s[j]>='A'&&s[j]<='Z') s[j]=s[j]+32;
		}
	
		if(jiaoji[s]==0)
		jiaoji[s]++;
		
		
		//cout<<jiaoji[s]<<endl;
		
	}
	//cout<<"容量"<< jiaoji.size()<< endl;
	
	for(int i=0;i<m;i++){
		cin>>s;
		for(int j=0;j<s.size();j++){
			if(s[j]>='A'&&s[j]<='Z') s[j]=s[j]+32;
		}
		
		if(jiaoji[s]==1){
			j++;
			jiaoji[s]=2;
		}
		else if(jiaoji[s]==0)
			jiaoji[s]=11100;
		else continue;
		
		//cout<<jiaoji[s]<<endl;
		
		//to thou art and
		
	}
//哈希表的大小就代表了并集
		cout<<j<<endl<< jiaoji.size();
	
	
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值