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;
}
运行效果
本文内容到此结束,欢迎指正交流!