C语言小练习 2
2017-04-29 21:25
253 查看
因为最近好多小伙伴问我实验报告五的第1题(熊老师课堂是实验报告六),所以专门来更新一篇博客~
题目是这样哒:
1.成绩排名
假设有五位同学四门功课的成绩如下,现要求得每位同学的总分,并按照总分从高到低的顺序进行排序,输出其名次,如果总分相同,则按语文和数学分数之和高者排前,低者排后,但名次一样。
因为大家还没有学到指针那一章节,所以下面的讲解内容将用数组来代替指针~
首先我们来看看这道题需要实现的功能有哪些:
1、读入所有姓名、科目、成绩信息
2、计算每位同学总分
3、按总分进行排序,若总分相同,按语数和排序
4、输出排名,要求相同分数排名一致
5、输出最终结果
接下来我们先实现第一步:
我们把这个表看做一个二维数组,我们可以把姓名一栏看做为数组的行标,科目一栏看做数组的列标,每一个成绩就是一个数组元素的值
![](https://img-blog.csdn.net/20170429212622728?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb21pbmd4aWFuc2Vu/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
比如李丹的数学成绩就是a[4][1]。(其实想写score[][],做图片的时候做错了,懒得改了╮(╯▽╰)╭)
这样子的话姓名和科目都有一个固定的数字去表示了,但是最后的结果虽然不用输出科目名称,但是需要输出学生姓名,所以我们再单独声明一个name[5]字符串数组,用于存放每个人的姓名,其姓名编号和上图中编号一致。第一步就完成啦。
接下来是第二步,计算每位同学的总分,为了方便总分的存储,所以我们在声明上面那个数组的同时,需要多声明一列,进行存储总分,他的编号就是4啦。
![](https://img-blog.csdn.net/20170429212756322?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb21pbmd4aWFuc2Vu/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
计算时,我们设置一个for循环,每次对每一行进行处理,将每一行的前面四个数的和计算出来放到第五个元素里面去,这样第二步就完成了。
下面是第3步,排序。
排序的方法比较多种多样,我们这里采用选择排序,即每次从前往后进行遍历,遍历到的数分别与后面的数依次比较,只要比后面的数小就和它交换。
但是这是一个二维数组,我们是要对每个同学的所有信息进行排序,所以每次交换需要交换一行。如果依次交换每一个行里的每一个元素,虽然也可以做到,但是会很麻烦,所以在这里为大家介绍在数据库管理中非常常用的索引法。
我们先建立一个索引数组index[5],对它进行循环赋值,使得它的每一个元素的值等于其下标。如果用相同的数字构建它与原来二维数组的关系的话,就可以看做每一个元素指向二维数组的每一行。
我们把index[]的每一个行标当做排名,每一个元素的值所代表的数字代表每一个人的姓名,每一个姓名都有其对应的每一个科目的成绩,及一行,那么每一个index[]就可以看做指向每一行的索引或者说指针。交换每一行的时候不必交换整行的数据,只用改变每一个index元素所指向的行就行了,也就是改变每一个下标(排名位置)所对应index的值(指向的行)。
![](https://img-blog.csdn.net/20170429212829590?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb21pbmd4aWFuc2Vu/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](https://img-blog.csdn.net/20170429212919404?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb21pbmd4aWFuc2Vu/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
这里要注意两点,一是数组下标是从0开始的,第二的时候是交换行的交换方式,就像指针变量与指针指向变量的值的区别一样,交换交换的是index索引,但是选择排序的比较过程是比较的每一行的总分成绩
总分成绩相等的时候,我们就加入一个if条件,其中的比较项就变成了语文和数学的成绩和,同样根据列下标进行引用就行,也要注意,比较的是成绩a[][]的值,交换的是索引index的值
第四步,因为相同总分虽然顺序不同,但是名词一样,所以我们要用rank排名数组进行处理,下标和名次(值)一样(注意,这里名次要与前面对应,所以是从0开始),在for循环时,遇到两个相同的时候就对此次下标对应的值自减一次。
(后来发现这里还是有缺陷的。。。比如出现三个一样的成绩的时候。。。加一个变量作为计数器,再循环自减计数器次数就行,不过我懒得改了。。。╮(╯▽╰)╭感觉自己好懒呀~)
第五步,循环输出所有信息就好啦~
下面是源代码:
题目是这样哒:
1.成绩排名
假设有五位同学四门功课的成绩如下,现要求得每位同学的总分,并按照总分从高到低的顺序进行排序,输出其名次,如果总分相同,则按语文和数学分数之和高者排前,低者排后,但名次一样。
姓 名 | 语 文 | 数 学 | 英 语 | 综 合 |
张大明 | 120 | 130 | 110 | 280 |
李小红 | 110 | 120 | 105 | 290 |
王志强 | 108 | 128 | 126 | 278 |
汪晓成 | 112 | 135 | 122 | 286 |
李 丹 | 100 | 120 | 108 | 276 |
因为大家还没有学到指针那一章节,所以下面的讲解内容将用数组来代替指针~
首先我们来看看这道题需要实现的功能有哪些:
1、读入所有姓名、科目、成绩信息
2、计算每位同学总分
3、按总分进行排序,若总分相同,按语数和排序
4、输出排名,要求相同分数排名一致
5、输出最终结果
接下来我们先实现第一步:
我们把这个表看做一个二维数组,我们可以把姓名一栏看做为数组的行标,科目一栏看做数组的列标,每一个成绩就是一个数组元素的值
比如李丹的数学成绩就是a[4][1]。(其实想写score[][],做图片的时候做错了,懒得改了╮(╯▽╰)╭)
这样子的话姓名和科目都有一个固定的数字去表示了,但是最后的结果虽然不用输出科目名称,但是需要输出学生姓名,所以我们再单独声明一个name[5]字符串数组,用于存放每个人的姓名,其姓名编号和上图中编号一致。第一步就完成啦。
接下来是第二步,计算每位同学的总分,为了方便总分的存储,所以我们在声明上面那个数组的同时,需要多声明一列,进行存储总分,他的编号就是4啦。
计算时,我们设置一个for循环,每次对每一行进行处理,将每一行的前面四个数的和计算出来放到第五个元素里面去,这样第二步就完成了。
下面是第3步,排序。
排序的方法比较多种多样,我们这里采用选择排序,即每次从前往后进行遍历,遍历到的数分别与后面的数依次比较,只要比后面的数小就和它交换。
但是这是一个二维数组,我们是要对每个同学的所有信息进行排序,所以每次交换需要交换一行。如果依次交换每一个行里的每一个元素,虽然也可以做到,但是会很麻烦,所以在这里为大家介绍在数据库管理中非常常用的索引法。
我们先建立一个索引数组index[5],对它进行循环赋值,使得它的每一个元素的值等于其下标。如果用相同的数字构建它与原来二维数组的关系的话,就可以看做每一个元素指向二维数组的每一行。
我们把index[]的每一个行标当做排名,每一个元素的值所代表的数字代表每一个人的姓名,每一个姓名都有其对应的每一个科目的成绩,及一行,那么每一个index[]就可以看做指向每一行的索引或者说指针。交换每一行的时候不必交换整行的数据,只用改变每一个index元素所指向的行就行了,也就是改变每一个下标(排名位置)所对应index的值(指向的行)。
这里要注意两点,一是数组下标是从0开始的,第二的时候是交换行的交换方式,就像指针变量与指针指向变量的值的区别一样,交换交换的是index索引,但是选择排序的比较过程是比较的每一行的总分成绩
总分成绩相等的时候,我们就加入一个if条件,其中的比较项就变成了语文和数学的成绩和,同样根据列下标进行引用就行,也要注意,比较的是成绩a[][]的值,交换的是索引index的值
第四步,因为相同总分虽然顺序不同,但是名词一样,所以我们要用rank排名数组进行处理,下标和名次(值)一样(注意,这里名次要与前面对应,所以是从0开始),在for循环时,遇到两个相同的时候就对此次下标对应的值自减一次。
(后来发现这里还是有缺陷的。。。比如出现三个一样的成绩的时候。。。加一个变量作为计数器,再循环自减计数器次数就行,不过我懒得改了。。。╮(╯▽╰)╭感觉自己好懒呀~)
第五步,循环输出所有信息就好啦~
下面是源代码:
#include<stdio.h> int main() { int score[5][5]= //输入成绩 { {120, 130, 110, 280, 0}, {110, 120, 105, 290, 0}, {108, 128, 126, 278, 0}, {112, 135, 122, 286, 0}, {100, 120, 108, 276, 0} }; int index[5], rank[5]; //建立索引和排名数组 int i,j,temp=0; char name[10][10] = //建立姓名数组 { {"张大明"}, {"李小红"}, {"王志强"}, {"汪晓成"}, {"李 丹"} }; for (i=0; i<=4; i++) //计算每位同学的总分 { for(j=0; j<=3; j++) temp += score[i][j]; score[i][4] = temp; temp = 0; } for(i=0; i<=4; i++) index[i] = i; //初始化索引数组 for(i=0; i<=3; i++) { for(j=i+1; j<=4; j++) { if(score[index[i]][4]<score[index[j]][4]) //按总分进行选择排序 { temp = index[i]; index[i] = index[j]; index[j] = temp; } else if(score[index[i]][4]==score[index[j]][4]) //如果出现总分相同,按语数和排序 { if((score[index[i]][0]+score[index[i]][1])<(score[index[j]][0]+score[index[j]][1])) { temp = index[i]; index[i] = index[j]; index[j] = temp; } } else; } } rank[0] = 1; //初始化排序数组首个元素 for(i=1; i<=4; i++) { rank[i] = i+1; if(score[index[i]][4]==score[index[i-1]][4]) //分数成绩相等的将名次一致 rank[i]--; //注意这里是有缺陷的,如果3个一样就没办法了 } //加个计数器就好了,但是我懒得改了╮(╯▽╰)╭ for(i=0; i<=4; i++) //输出结果 { printf("%s", name[index[i]]); printf(" total score=%d",score[index[i]][4]); printf(" rank:%d\n",rank[i]); } return 0; }
相关文章推荐
- C语言 关于冒泡排序的过程 练习
- c语言练习 10-2. 删除字符串中的子串(20)
- 每日练习2-C语言
- C语言射击游戏练习程序
- 【c语言练习】2.0
- 一些可以使你感兴趣的c语言简单练习
- C语言递归练习
- 蓝桥杯 基础练习 Huffuman树 (C语言)
- C语言编程(练习2:循环,三大循环结构 )
- C语言编程练习(day of the year)
- C语言-练习笔记
- C语言循环结构练习1
- C语言编程(练习4:分支和跳转 )
- C语言第四课练习
- 第04天C语言(08):while练习3
- C语言实验——Hello World!(printf练习)
- 第04天C语言(19):循环嵌套练习03
- 【C语言】练习1-23
- C语言 指针练习-选择排序法
- 【C语言】练习3-3