C++: 朋友圈点赞

https://blog.csdn.net/NGUever15/article/details/88879891

朋友圈点赞

问题描述

朋友圈有一个点赞功能,你可以为你喜欢的文章点赞表示支持。每篇文章都可以根据其内容给出一些标签,这些标签用数字表示(如:1代表心灵鸡汤、2代表政治、3代表经济…),你点赞的文章的类型,也间接反应了你的喜好。

本关要求你写一个完整的程序,通过统计一个人点赞的纪录,分析这个人的喜好。

输入格式

第一行输入一个正整数N(N<1000),是该用户点赞的文章数量。

随后的N行,每行给出一篇被其点赞的文章的标签描述,格式为" k k k s 1 s_1 s1 s 2 s_2 s2 s k s_k sk"
其中:
k表示该文章的标签数,1≤k≤10,即每篇文章最多10个标签;
s k s_k sk​​ 是标签,是1到1000之间的整数,即总共有不超过1000种标签。

所有数值之间以空格分隔。

输出格式

统计所有被点赞的文章中最常出现的那个标签,在一行中输出它的标签编号和出现次数,数字间隔1个空格。如果有并列,则输出编号最大的那个。

例如输入:
4
3 889 233 2
5 100 3 233 2 73
4 3 73 889 2
2 233 123
则输出为:
233 3

上述示例中出现最多次(3次)的标签有233和2,存在并列时,输出最大的那个标签233,然后输出其出现的次数3。

测试样例

测试输入:
4
3 889 233 2
5 100 3 233 2 73
4 3 73 889 2
2 233 123
预期输出:
233 3

测试输入:
8
3 12 45 2
4 1 334 45 7
3 7 12 8
2 2 12
5 45 67 2 3 1
3 23 12 6
2 12 2
4 45 12 7 8
预期输出:
12 6

解题思路

获取输入数据

首先要获取输入数据,并将其存储在a[1000][11]中,a[][0]中存储的是每一篇文章的标签数量。

int n;
	cin>>n;
	int a[1000][11];
	for(int i=0;i<n;i++){ //n篇文章
		cin>>a[i][0];//获得第i篇文章的 标签数量
		for(int j=1;j<=a[i][0];j++){
			cin>>a[i][j];
		}
	}

统计每一个标签出现的次数

声明一个标签数组label
对应的也声明一个记录标签对应出现次数的数组num_label
再声明一个变量total_label,用以记录出现的标签的总数。
思路:
遍历a中的有效数据,发现了之前没有出现过的标签,则将新标签,添加到标签数组label中去,没有这个标签以前出现过了,那么要将其对应的num_label+1。
这里需要一个辅助函数in_array(),用来判断某个标签是否在label中出现过,如果出现过,也还返回其对应的在label中的下标。

in_array()实现如下:

int in_array(int a[],int k){
	for(int i=0;a[i]!='\0';i++){
		if(a[i]==k){
			return i; //返回位置
		}
	}
	return -1;
}

如果该标签未在label中出现过,则返回-1。
对于未出现过的情况:

  • 在label中添加新的标签,通过total_label这个变量来索引到数组最末尾的位置。
  • label对应的num_label的值要加一。初始化时都为0。
  • 总的标签数量total_label要加一。

对于出现过的情况:

  • label对应的num_label的值要加一即可。

代码实现如下:

	int label[1000];
	int total_label = 0;
	int num_label[1000]={0};
	for(int i=0;i<n;i++){
		for(int j=1;j<=a[i][0];j++){
			int site = in_array(label,a[i][j]);
			if(site==-1){
				label[total_label]=a[i][j];
				num_label[total_label]++;
				total_label++;
			}
			else{
				num_label[site]++;
			}
		}
	}

找到最大的统计量以及对应标签的index

声明max 来存储最大统计量的值
声明数组max_index用来存储拥有最大统计量的标签在label中的index
声明变量num_max用来记录具有最大统计的label的个数。
对所有的num_label做遍历。
如果其值大于max,则它就是max,此时num_max的值回到1。并且将其下边记录到max_index中。
如果其值等于max,则num_max值加一,并且将其下边记录到max_index中。
具体代码实现如下:

	int max = 0;
	int max_index[1000];
	int num_max = 0;
	for(int i=0;i<total_label;i++){
		if(num_label[i]>max){
			max = num_label[i];
			num_max = 1;
			max_index[num_max]=i;
		}
		else if(num_label[i]==max){
			num_max++;
			max_index[num_max]=i;
		}
	}

获取拥有最大统计量的最大label以及最大统计量

此时分两种情况讨论。
最大统计量只有一个:
直接获取且下标,找到label即可。

最大统计量有多个:
此时需要遍历max_index中对应的label的值,需要对齐逐一进行比较,直到找到最大值。

具体代码实现如下:

if(num_max == 1){
		int index = max_index[1];
		cout<<label[index]<<" "<<max<<endl;
	}
	else{  // 此时需要比较大小
		int max_label = 0;
		for(int i=1;i<=num_max;i++){
			if(label[max_index[i]]>max_label)
				max_label = label[max_index[i]];
		}
		cout<<max_label<<" "<<max<<endl;
	}

运行效果

在这里插入图片描述

GitHub源码地址

本文内容到此结束,欢迎指正交流!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Summer tree

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值