Repository navigation
Expand file tree
/
Copy pathcount_score.c
More file actions
402 lines (371 loc) · 15.2 KB
/
Copy pathcount_score.c
File metadata and controls
402 lines (371 loc) · 15.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
#include <stdio.h>
#include <string.h>
#define MAX_SCHOOLS 10 // 学校数量
#define MAX_PROJECTS 10 // 项目数量
#define MAX_NAME_LENGTH 20 // 最大名字长度
/* 运动员信息 */
typedef struct {
int athleteID; // 运动员ID
char athleteName[MAX_NAME_LENGTH]; // 运动员姓名
int sex; // 性别(0-女,1-男)
int schoolID; // 所属学校对应的ID
int projectID; // 参加项目的ID
int score; // 得分
int schoolRank; // 校排名
int meetingRank; // 整个运动会排名
} Athlete;
/* 学校信息 */
typedef struct {
int schoolID; // 学校ID
char schoolName[MAX_NAME_LENGTH]; // 学校名字
int totalMaleScore; // 男生项目总分
int totalFemaleScore; // 女生项目总分
int totalTeamScore; // 团体项目总分
int projectScores[MAX_PROJECTS]; // 每一个项目对应的分数
// int projectRanks[MAX_PROJECTS]; // 每一个项目对应的排名
} School;
/* 项目信息 */
typedef struct {
int projectID; // 项目ID
char projectName[MAX_NAME_LENGTH]; // 项目名称
int projectType; // 项目类型(2-男女团体项目 1-男生项目 0-女生项目)
} Project;
/* 运动会信息 */
typedef struct {
int numSchools; // 学校总数
int numAthletes; // 运动员总数
int numMaleProjects; // 男生项目总数
int numFemaleProjects; // 女生项目总数
int numTeamProjects; // 团体项目总数
Project projects[MAX_PROJECTS]; // 存储全部项目信息
School schools[MAX_SCHOOLS]; // 存储全部学校的信息
Athlete athletes[MAX_SCHOOLS * (MAX_PROJECTS + 1)]; // 存储全部运动员的信息
} SportsMeeting;
void initializeSportsMeeting(SportsMeeting *meeting) {
/* 初始化运动会信息 */
meeting->numSchools = 0;
meeting->numAthletes = 0;
meeting->numMaleProjects = 0;
meeting->numFemaleProjects = 0;
meeting->numTeamProjects = 0;
}
int isExistsProject(SportsMeeting *meeting, int projectID) {
/* 判断项目是否存在(二分查找) */
int length = meeting->numFemaleProjects + meeting->numMaleProjects + meeting->numTeamProjects;
int low = 0, mid, high = length - 1;
while (low <= high) {
mid = (low + high) / 2;
if(meeting->projects[mid].projectID == projectID) {
return 1; // 项目存在
}
else if(meeting->projects[mid].projectID < projectID) {
low = mid + 1;
}
else {
high = mid - 1;
}
}
return 0; // 项目不存在
}
int isExistsSchool(SportsMeeting *meeting, int schoolID) {
/* 判断学校是否存在(二分查找) */
int length = meeting->numSchools;
int low = 0, mid, high = length - 1;
while (low <= high) {
mid = (low + high) / 2;
if(meeting->schools[mid].schoolID == schoolID) {
return 1; // 学校存在
}
else if(meeting->schools[mid].schoolID < schoolID) {
low = mid + 1;
}
else {
high = mid - 1;
}
}
return 0; // 学校不存在
}
void addSchool(SportsMeeting *meeting, const char *schoolName) {
/* 添加学校信息 */
if(meeting->numSchools >= MAX_SCHOOLS) { // 数组下标越界
printf("Error in schoolName '%s'.\nIndexError:Index out of range.", schoolName);
return;
}
School *school = &(meeting->schools[meeting->numSchools]); // 获取新增的学校信息
school->schoolID = meeting->numSchools + 1; // 学校id自增长,无需手动添加
strcpy(school->schoolName, schoolName); // 添加学校姓名
school->totalMaleScore = 0; // 初始化学校男生项目总分为0
school->totalFemaleScore = 0; // 初始化学校女生项目总分为0
school->totalTeamScore = 0; // 初始化学校团体项目总分为0
// 初始化每一个项目得分和排名
for (int i = 0; i < MAX_PROJECTS; i++) {
school->projectScores[i] = 0;
// school->projectRanks[i] = -1;
}
meeting->numSchools++; // 参与运动会的学校数量+1
}
void addProject(SportsMeeting *meeting, const char *projectName, int projectType) {
/* 添加项目编号 */
if(projectType != 1 && projectType != 0 && projectType != 2) { // 填写的项目性别不正确
printf("Error in projectName '%s'.\nSexError:This sex not found.", projectName);
return;
}
int numProjects = meeting->numFemaleProjects + meeting->numMaleProjects + meeting->numTeamProjects; // 所有项目总数
if(numProjects >= MAX_PROJECTS) { // 项目总数超出数组范围
printf("Error in projectName '%s'.\nIndexError:Index out of range.", projectName);
return;
}
Project *project = &(meeting->projects[numProjects]);
project->projectID = numProjects + 1; // 项目id自增长
project->projectType = projectType; // 标记该项目的性别
strcpy(project->projectName, projectName); // 添加项目姓名
// 添加项目类型
if(projectType) {
project->projectType == 1 ? meeting->numMaleProjects++ : meeting->numTeamProjects++;
}
else {
meeting->numFemaleProjects++;
}
}
void addAthlete(SportsMeeting *meeting, const char *name, int schoolID, int projectID, int score, int sex) {
/* 添加运动员信息 */
if(sex != 1 && sex != 0) { // 性别不存在
printf("Error in athleteName '%s'.\nSexError:This sex not found.", name);
return;
}
if(meeting->numAthletes >= MAX_SCHOOLS * (MAX_PROJECTS + 1)) { // 运动员总数超出数组范围
printf("Error in athleteName '%s'.\nIndexError:Index out of range.", name);
return;
}
if(!isExistsSchool(meeting, schoolID)) { // 学校不存在
printf("Error in athleteName '%s'.\nDoesNotExistError:This school not found.", name);
return;
}
if(!isExistsProject(meeting, projectID)) { // 项目不存在
printf("Error in athleteName '%s'.\nDoesNotExistError:This project not found.", name);
return;
}
if(sex) {
if(meeting->projects[projectID - 1].projectType == 0) { // 运动员是男的,可他报了女生的项目
printf("Error in athleteName '%s'.\nMatchError:Sex mismatch.", name);
return;
}
}
else {
if(meeting->projects[projectID - 1].projectType == 1) { // 运动员是女的,可他报了男生的项目
printf("Error in athleteName '%s'.\nMatchError:Sex mismatch.", name);
return;
}
}
Athlete *athlete = &(meeting->athletes[meeting->numAthletes]);
strcpy(athlete->athleteName, name); // 运动员姓名
athlete->sex = sex; // 运动员性别
athlete->athleteID = meeting->numAthletes + 1; // 运动员id自增长
athlete->schoolID = schoolID; // 运动员关联的学校ID
athlete->projectID = projectID; // 项目编号
athlete->score = score; // 得分
athlete->schoolRank = -1; // 初始化运动员校排名
athlete->meetingRank = -1; // 初始化运动员运动会排名
meeting->numAthletes++; // 运动员总数+1
}
void calculateScores(SportsMeeting *meeting) {
/* 汇总学校总分和各项目得分 */
for (int i = 0; i < meeting->numAthletes; i++) {
Athlete *athlete = &(meeting->athletes[i]);
School *school = &(meeting->schools[athlete->schoolID - 1]);
if(athlete->projectID == 2) {
school->totalTeamScore += athlete->score; // 统计团体项目总分
}
else {
if(athlete->sex) {
school->totalMaleScore += athlete->score; // 统计男生总分
}
else {
school->totalFemaleScore += athlete->score; // 统计女生总分
}
}
school->projectScores[athlete->projectID - 1] += athlete->score; // 统计这个项目的总分
}
}
void queryAthletesScore(SportsMeeting *meeting) {
/* 查询每个运动员得分情况 */
printf("所有运动员得分情况如下:\n");
printf("男生得分情况:\n");
for (int i = 0; i < meeting->numAthletes; i++) {
Athlete *athlete = &(meeting->athletes[i]); // 获取第i个学生
School *school = &(meeting->schools[athlete->schoolID - 1]); // 获取第i个学生对应的学校
if(athlete->sex) {
printf("运动员姓名:%s\t运动员编号:%d\t所属学校:%s\t项目名称:%s\t总分:%d\n", athlete->athleteName, athlete->athleteID, school->schoolName, meeting->projects[athlete->projectID - 1].projectName, athlete->score);
}
}
printf("\n女生得分情况:\n");
for (int i = 0; i < meeting->numAthletes; i++) {
Athlete *athlete = &(meeting->athletes[i]); // 获取第i个学生
School *school = &(meeting->schools[athlete->schoolID - 1]); // 获取第i个学生对应的学校
if(!athlete->sex) {
printf("运动员姓名:%s\t运动员编号:%d\t所属学校:%s\t项目名称:%s\t总分:%d\n", athlete->athleteName, athlete->athleteID, school->schoolName, meeting->projects[athlete->projectID - 1].projectName, athlete->score);
}
}
}
void querySchoolTotalScore(SportsMeeting *meeting) {
/* 按学校编号查询各个学校的总分 */
for (int i = 0; i < meeting->numSchools; i++) {
School *school = &(meeting->schools[i]);
printf("学校编号:%d\t学校名称:%s\t总分:%d\n", school->schoolID, school->schoolName, school->totalMaleScore + school->totalFemaleScore);
}
}
int *BubbleSort(SportsMeeting *meeting, int *athletesID, int length) {
/* 按数组中的运动员ID访问对应的分数并按照该分数排序(冒泡排序) */
int *data = athletesID;
int c;
for(int i = 1; i < length; i++) {
for(int j = 0; j < length - i; j++) {
if(meeting->athletes[data[j] - 1].score < meeting->athletes[data[j + 1] - 1].score) {
c = data[j];
data[j] = data[j + 1];
data[j + 1] = c;
}
}
}
return data;
}
void addAthleteMeetingRank(SportsMeeting *meeting, int *athletesID, int length) {
/* 添加运动员运动会排名 */
int *sortData = BubbleSort(meeting, athletesID, length); // 接收已经排序好的数据
int athleteId; // 储存某个运动员的id
// 从排好序的数据中进行遍历并添加排名
for(int rank = 0; rank < length; rank++) {
athleteId = sortData[rank];
meeting->athletes[athleteId - 1].meetingRank = rank + 1;
}
}
void calculateAthleteMeetingRank(SportsMeeting *meeting) {
/* 计算运动员运动会的排名 */
int numProjects = meeting->numFemaleProjects + meeting->numMaleProjects + meeting->numTeamProjects; // 获取总项目数量
int athletesID[meeting->numAthletes], length;
// 从总项目数量中开始遍历,再从每一个运动员里遍历,如果运动员的项目相同,那么将运动员的ID加入athletesID数组中存放
for(int i = 0; i < numProjects; i++) {
length = 0;
for(int j = 0; j < meeting->numAthletes; j++) {
Athlete *athlete = &(meeting->athletes[j]);
if(athlete->projectID == i + 1) {
athletesID[length] = athlete->athleteID;
length++;
}
}
addAthleteMeetingRank(meeting, athletesID, length);
}
}
void queryProjectsScore(SportsMeeting *meeting) {
/* 按项目查询运动员得分情况 */
int numProjects = meeting->numMaleProjects + meeting->numFemaleProjects + meeting->numTeamProjects; // 计算总项目数
calculateAthleteMeetingRank(meeting); // 统计运动员的运动会排名
// 遍历所有项目
for(int i = 0; i < numProjects; i++) {
printf("项目名为《%s》的每个学生得分情况如下:\n", meeting->projects[i].projectName);
for(int j = 0; j < meeting->numAthletes; j ++) {
Athlete *athlete = &(meeting->athletes[j]);
if(athlete->projectID == i + 1) {
printf("运动员姓名:%s\t所属学校:%s\t得分:%2d\t运动会排名:%2d\n", athlete->athleteName, meeting->schools[athlete->schoolID - 1].schoolName, athlete->score, athlete->meetingRank);
}
}
printf("\n");
}
}
void querySchoolScore(SportsMeeting *meeting, int schoolID, int projectID) {
/* 查询某个学校某个项目的得分情况 */
if(!isExistsSchool(meeting, schoolID)) { // 学校不存在
printf("DoesNotExistError:This school not fount.");
return;
}
if(!isExistsProject(meeting, projectID)) { // 项目不存在
printf("DoesNotExistError:This project not fount.");
return;
}
School *school = &meeting->schools[schoolID - 1];
Project *project = &meeting->projects[projectID - 1];
int is_null = 0;
printf("%s的'%s'得分情况:\n", school->schoolName, project->projectName);
// 从所有运动员中遍历,若运动员的学校id和项目id与查询的一致,则输出结果
for(int i = 0; i < meeting->numAthletes; i++) {
Athlete *athlete = &meeting->athletes[i];
if(athlete->projectID == projectID && athlete->schoolID == schoolID) {
printf("运动员:%s\t得分:%d\n", athlete->athleteName, athlete->score);
is_null = 1;
}
}
if(!is_null) {
printf("该学校暂无运动员参与该项目。");
}
}
void queryProjectRank(SportsMeeting *meeting, int projectID) {
/* 按项目编号查询前几的学校 */
if(!isExistsProject(meeting, projectID)) { // 项目不存在
printf("DoesNotExistError:This project not fount.");
return;
}
School *school;
int length = 0, c;
int schoolsID[meeting->numSchools];
// 将学校id存入schoolsID数组中
for(int i = 0; i < meeting->numSchools; i++) {
school = &meeting->schools[i];
schoolsID[length] = school->schoolID;
length++;
}
// 从数组schoolsID中拿出学校id并查询对应项目的得分并且排好序
for(int i = 1; i < meeting->numSchools; i++) {
for(int j = 0; j < meeting->numSchools - i; j++) {
if(meeting->schools[j].projectScores[projectID - 1] < meeting->schools[j + 1].projectScores[projectID - 1]) {
c = schoolsID[j];
schoolsID[j] = schoolsID[j + 1];
schoolsID[j + 1] = c;
}
}
}
// 从排好序的schoolsID数组中依次拿出学校id并输出信息
for(int i = 0; i < meeting->numSchools; i++) {
int schoolID = schoolsID[i];
printf("排名:%d\t学校:%s\t\t总分:%d\t项目名称:%s\n", i + 1, meeting->schools[schoolID - 1].schoolName, meeting->schools[schoolID - 1].projectScores[projectID - 1], meeting->projects[projectID - 1].projectName);
}
}
int main() {
SportsMeeting meeting;
initializeSportsMeeting(&meeting);
// 添加学校
addSchool(&meeting, "北京大学");
addSchool(&meeting, "北京体育大学");
addSchool(&meeting, "清华大学");
// 添加项目
addProject(&meeting, "男子1000米", 1); // 男子项目
addProject(&meeting, "男子100米", 1); // 男子项目
addProject(&meeting, "女子800米", 0); // 女子项目
addProject(&meeting, "女子100米", 0); // 女子项目
addProject(&meeting, "男女混合接力", 2); // 团体项目
// 添加运动员信息
addAthlete(&meeting, "苏炳添", 3, 2, 10, 1);
addAthlete(&meeting, "陈梦", 2, 3, 5, 0);
addAthlete(&meeting, "孙颖莎", 3, 4, 3, 0);
addAthlete(&meeting, "李盈莹", 2, 4, 6, 0);
addAthlete(&meeting, "武大靖", 2, 2, 11, 1);
addAthlete(&meeting, "马龙", 1, 1, 12, 1);
addAthlete(&meeting, "张继科", 1, 1, 8, 1);
addAthlete(&meeting, "吴志强", 1, 5, 8, 1);
addAthlete(&meeting, "陈冠锋", 3, 5, 9, 1);
addAthlete(&meeting, "葛曼棋", 2, 5, 11, 0);
addAthlete(&meeting, "梁小静", 3, 5, 8, 0);
calculateScores(&meeting); // 对数据进行汇总
querySchoolScore(&meeting, 2, 2); // 按学校、项目编号查询得分情况
queryProjectsScore(&meeting); // 按项目查询得分情况
querySchoolTotalScore(&meeting); // 查询各学校总分
queryAthletesScore(&meeting); // 查询所有运动员得分
queryProjectRank(&meeting, 5); // 按项目编号查询前三或前五的学校
return 0;
}
/* 能实现的功能:
* 按项目编号查询前三或前五的学校 √
* 按学校编号查询学校某个项目的得分情况 √
* 查询前三名或者前五名的项目编号、运动员姓名、排名、成绩 √
* 查询每个项目中的学生的得分情况 √
* 统计每个学校的总分 √
* */