本来准备发最近的第34次ccf认证的,但好像最近貌似要查重就暂时等一下吧,先发点之前的。
(还有在抱怨一句,我为什么这次(34次)没考到300+。~_~)
那就来看看第33次ccf-csp的:
第一题:
在学习了文本处理后,小 P 对英语书中的 𝑛n 篇文章进行了初步整理。 具体来说,小 P 将所有的英文单词都转化为了整数编号。假设这 𝑛n 篇文章中共出现了 𝑚m 个不同的单词,则把它们从 11 到 𝑚m 进行编号。 这样,每篇文章就简化为了一个整数序列,其中每个数都在 11 到 𝑚m 范围内。
现给出小 P 处理后的 𝑛n 篇文章,对于每个单词 𝑖i(1≤𝑖≤𝑚1≤i≤m),试统计:
- 单词 𝑖i 出现在了多少篇文章中?
- 单词 𝑖i 在全部文章中总共出现了几次?
题目其余就不再叙述了,大概意思就是让你统计每个数字出现在几个里面,和每个数字出现的总次数。我们考虑到为了更好的理解,不造成混淆,首先定义一个结构体用于记录每个数字的编号和出现的次数。(不要问为什么用typedef,这里是一点个人习惯)
typedef struct no{
int id;
int x;
int y;
}node;
读入n和m后,采取读一个数据处理一个数据,这样可以减少对内存的占用,若为每个元素对应的id号,则对应的y加一,x改为1;
总代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef struct no{
int id;
int x;
int y;
}node;
int main()
{
node nod[101];
int n,m,i,j,l,nei,k,pp[101]={0};
cin>>n>>m;
for(i=1;i<=m;i++)
{
nod[i].id=i;
nod[i].y=0;
nod[i].x=0;
}
for(i=1;i<=n;i++)
{
cin>>l;
for(int kk=1;kk<=m;kk++)
pp[kk]=0;
for(j=1;j<=l;j++)
{
cin>>nei;
for(k=1;k<=m;k++)
{
if(nei==nod[k].id)
{
nod[k].y++;
pp[k]=1;
}
}
}
for(int kk=1;kk<=m;kk++)
{
if(pp[kk]==1)
nod[kk].x++;
}
}
for(i=1;i<=m;i++)
{
cout<<nod[i].x<<" "<<nod[i].y<<endl;
}
}
第二题:
除了进行简单的词频统计,小 P 还希望使用 Jaccard 相似度来评估两篇文章的相似性。 具体来说,每篇文章均由若干个英文单词组成,且英文单词仅包含“大小写英文字母”。 对于给定的两篇文章,小 P 首先需要提取出两者的单词集合 𝐴A 和 𝐵B,即去掉各自重复的单词。 然后计算出:
- ∣𝐴∩𝐵∣∣A∩B∣,即有多少个不同的单词同时出现在两篇文章中;
- ∣𝐴∪𝐵∣∣A∪B∣,即两篇文章一共包含了多少个不同的单词。
最后再将两者相除即可算出相似度。 需要注意,在整个计算过程中应当忽略英文字母大小写的区别,比如
the
、The
和THE
三者都应被视作同一个单词。试编写程序帮助小 P 完成前两步,计算出 ∣𝐴∩𝐵∣∣A∩B∣ 和 ∣𝐴∪𝐵∣∣A∪B∣;小 P 将亲自完成最后一步的除法运算。
其余题目就不再叙述了,总的来说就是输入两个行,忽略大小写的影响,判断有多少个相同的,和总共多少个不同的。
这个题目由于读入一行数据,其中包含空格在内,为了方便后续的处理,这里采用vector(矢量)存放每一段中的每个不同单词,在输入时要注意删除空格的影响,可采用如下的方式:
getline(cin,str1);
istringstream ss(str1);
string op;
while(ss>>op)
{
ops1.push_back(op);
}
这样就规避了空格。后面处理部分就是扫一个判断一个(这里当时做的时候多少有点那个,调了很长时间)
代码如下:
#include<bits/stdc++.h>
using namespace std;
vector<string> ops1,ops2;
int n,m;
int main()
{
string str1,str2;
int i,j;
cin>>n>>m;
cin.get();
getline(cin,str1);
getline(cin,str2);
istringstream ss(str1);
string op;
while(ss>>op)
{
ops1.push_back(op);
}
istringstream sss(str2);
string op2;
while(sss>>op2)
{
ops2.push_back(op2);
}
for(i=0;i<n;i++)
{
for(j=0;j<ops1[i].size();j++)
if(ops1[i][j]<='Z'&&ops1[i][j]>'A')
ops1[i][j]=ops1[i][j]-'A'+'a';
}
for(i=0;i<m;i++)
{
for(j=0;j<ops2[i].size();j++)
if(ops2[i][j]<='Z'&&ops2[i][j]>'A')
ops2[i][j]=ops2[i][j]-'A'+'a';
}
sort(ops1.begin(),ops1.end());
for(i=0;i<n-1;i++)
{
if(ops1[i]==ops1[i+1])
{
// cout<<ops1[i+1]<<endl;
for(j=i+1;j<n-1;j++)
ops1[j]=ops1[j+1];
n--;
i--;
}
}
sort(ops2.begin(),ops2.end());
for(i=0;i<m-1;i++)
{
if(ops2[i]==ops2[i+1])
{
for(j=i+1;j<m-1;j++)
ops2[j]=ops2[j+1];
m--;
i--;
}
}
int he=0,all=0,bin;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(ops1[i]==ops2[j])
{
he++;
}
}
}
all=m+n;
bin=all-he;
cout<<he<<endl;
cout<<bin;
}