第33次ccf-csp计算机职业资格认证第1,2题

本来准备发最近的第34次ccf认证的,但好像最近貌似要查重就暂时等一下吧,先发点之前的。

(还有在抱怨一句,我为什么这次(34次)没考到300+。~_~)

那就来看看第33次ccf-csp的:

第一题:

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

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

  1. 单词 𝑖i 出现在了多少篇文章中?
  2. 单词 𝑖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∣,即两篇文章一共包含了多少个不同的单词。

最后再将两者相除即可算出相似度。 需要注意,在整个计算过程中应当忽略英文字母大小写的区别,比如 theThe 和 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;
}

  • 21
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值