写在前面
这道题总体来说还是偏难的,如果只看代码比较难以理解,当结构体的文章发出后,就有许多小伙伴问我这个问题,我开始意识到,可能我对这道题所作的解答还不够(不装了😁,根本没有解答),所以我又回头看了看这道题,下面是我的一些个人理解,希望对各位小伙伴有帮助。
没看懂题目?
目的就是统计生日相同的学生,并输出他们的信息。
-
看输入部分。第一行是5,接下来5行,每一行都是学生学号、生日,这就很好办,不是难点,一个for循环就能搞定,**但是以何种形式存储才能在要处理时方便一些?**相信大家一定一头雾水,大家继续往下看…
-
看输出部分。第一行是生日+两个学号,第二行也是同样的生日+两个学号,这里就稍微有些棘手了,**怎样让生日相同的学生学号一并输出?**我们先按下不表
不清楚结构体?
看完了输入和输出部分,就剩中间最难的部分了,别急,先做好准备工作,我们来回答上面的第一个问题:以何种形式存储较好。
答:我们考的就是结构体当然就以结构题的形式来存储了,先声明这样一个的结构体类型,并同时定义一个结构体数组stu[50]可以用来存放50个学生的信息,我称其为输入数组
第二个结构体类型又是怎样一回事呢?
这时我们就可以回答上面的第二个问题:怎样让生日相同的学生学号一并输出?
-
答:相信你能猜到
char ids[50][6]
的作用了,没错这就是用来存生日相同的学生的五位学号+'\0’的。例如,1月10日有两位学生生日相同,将他们的学号分别存入bir[0].ids[0]和bir[0].ids[1]中,第二个结构体数组,我称之为输出数组。 -
学的好的话,
bir[50]={ 0 }
,就会知道我们把初始的50个数组中的nums
全部赋初值为0, -
这里面的
nums
相当于一个计数器,用来记录生日相同的学生有几个,如果有生日相同的学生,num就+1。
不理解变量含义?
n 用来存储学生个数
i , j 主要用于循环变量
k 用来记录输出数组中生日不相同的学生数量,例如输出数组中有四名学生,有三名生日都相同,则k就等于2
搞不懂执行情况?
好了,卖了这么多的关子,相信你已经对题目比较了解了。接下来看中间部分
结合实际例子可能比较容易理解,就按照题目给出的示例来解释。示例中n=5,所以就会执行5次大循环。
5
00001 1 10
00002 2 24
00003 1 10
00004 12 21
00005 12 21
-
第一次大循环。 j = 0、k = 0,所以第一个小循环( for循环 )就不会执行了,继续下面看
if(j == k)
,这个循环就可以执行,此时就会把第一个学生的信息(00001 1 10
)由输入数组(stu[0])存进输出数组(bir[0]),顺带将num
置为1,k
置为1,第一次大循环结束。 -
第二次大循环。 j = 0、k = 1,则进入第一个小循环( for循环 )且仅执行一次,判断第二位同学的生日(
00002 2 24
)和输入数组(stu[0])中学生生日不同。继续执行下面代码,此时 j = 1、k = 1,if(j == k)
符合条件,此时就会把第二个学生的信息(00002 2 24
)由输入数组存进输出数组中的第二个位置上( bir[1] ),顺带将第二个位置上的num置为1( bir[1].num = 1),k置为2,第二次大循环结束。 -
第三次大循环,j = 0、k = 2,则进入第一个小循环( for循环 ),将第三位同学的生日(
00003 1 10
)和输出数组中的两位同学生日( bir[0]和bir[1] )比较,判断出和输出数组中第一位同学生日相同( bir[0] ),就直接退出第一个小循环。此时 j = 0、k = 2,所以if(j == k)
就不符合条件,执行else
语句,将第三名同学( stu[2] )的学号存进输出数组( bir[0].ids[1],注意bir[0].ids[0]存的是第一位同学的学号 ),并将bir[0].num置为2。 -
第四次大循环, j = 0、k = 2,则进入第一个小循环,判断输入数组中第四位( stu[3] )和输出数组中学生生日都不同,此时 j = 2、k = 2,所以
if(j == k)
符合条件,就把第四位同学的生日信息由输入数组存入输出数组(bir[3])中,并将num置为1,k置为3。第四次大循环结束。 -
第五次大循环,j=0、k=3,则进入第一个小循环,将第五位同学的生日(
00003 1 10
)和输出数组中的三位同学生日比较,判断和第三位同学( bir[2] )生日相同,就直接退出第一个小循环。此时j = 3、k = 3,if(j == k)
符合条件,此时就会把第五个学生的信息(00005 12 21
)由输入数组存进输出数组中的第三个位置上,顺带将第三个位置上的num置为2,k置为4,第五次大循环结束。
完整代码
#include <iostream>
using namespace std;
#include<string.h>
/********** Begin **********/
struct stuinfo //储存输入学生的信息,简称输入数组
{char id[6];int month;int day;
}stu[50]; //给50的空间是因为0<=n<50struct birs //储存输出学生的信息,简称输出数组
{int nums;int month;int day;char ids[50][6];
}bir[50]={0};void Count()
{int n,i,j,k=0;scanf("%d",&n);//输入n个学生信息for(i=0;i<n;i++)scanf("%s%d%d",stu[i].id,&stu[i].month,&stu[i].day);//处理for(i=0;i<n;i++){//主要判断 输入数组 中的学生和 输出数组 中的每一个学生生日是否相同for(j=0;j<k;j++){if(bir[j].month == stu[i].month && bir[j].day == stu[i].day)break;}//将不同生日的学生分开存放if(j==k){bir[k].day = stu[i].day;bir[k].month = stu[i].month;strcpy(bir[k].ids[0],stu[i].id);bir[k].nums = 1;k++;}//将相同生日的学生放在一起else{strcpy(bir[j].ids[bir[j].nums],stu[i].id);bir[j].nums++;}}//输出for(i=0;i<k;i++){//只输出同一天生日学生数>=2的数组if(bir[i].nums > 1){printf("%d %d ",bir[i].month,bir[i].day);for(j=0;j<bir[i].nums;j++)printf("%s ",bir[i].ids[j]);printf("\n");}}
}
/********** End **********/
总结
通过对这道题的解析,相信大家已经都理解了。当然这只是其中一种解题思路,可能还有更好的方法,欢迎大家在评论区里分享。最后,希望大家在遇到困难时不要放弃,多想想,多尝试尝试!