词频统计
题目描述
在学习了文本处理后,小 P 对英语书中的 nn 篇文章进行了初步整理。 具体来说,小 P 将所有的英文单词都转化为了整数编号。假设这 nn 篇文章中共出现了 mm 个不同的单词,则把它们从 11 到 mm 进行编号。 这样,每篇文章就简化为了一个整数序列,其中每个数都在 11 到 mm 范围内。
现给出小 P 处理后的 nn 篇文章,对于每个单词 ii(1≤i≤m1≤i≤m),试统计:
- 单词 ii 出现在了多少篇文章中?
- 单词 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∣,即两篇文章一共包含了多少个不同的单词。
最后再将两者相除即可算出相似度。 需要注意,在整个计算过程中应当忽略英文字母大小写的区别,比如 the
、The
和 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();
}