(1)计算每个学生的总分和平均分;
(2)按总分成绩由高到低排出成绩的名次;
(3)打印出名次表,表格内包括学生编号、各科分数、总分和平均分;
(4)任意输入一个学号,能够查找出该学生在班级中的排名及其考试分数。
这个题C++程序设计基础第六版相对应的实验课的题目(完整的代码放在下面啦)。
我没有用数据结构,只用了数组,想分享的是给学生排名的方法。
具体情境:我发现如果要按照总成绩用冒泡给学生排名的话,会造成只交换了总成绩的情况。因为当时我没学数据结构,而且也没学到用指针计算排名,所以想到了下面的方法。
(1)创建数组+给数组赋值+计算平均成绩与总成绩
int grades[30][3]{};
void as_grades()
{
srand((unsigned)time(NULL));
for (int i = 0; i < 30; i++)
{
for (int j = 0; j < 3; j++)
{
grades[i][j] = rand() % (100 - 60 + 1) + 60;
}
}
}
这一段代码是随机生成60-100范围内的数字,因为题目中没有给出学生成绩,所以我要自己给学生的成绩赋值。
int sum_grades[30]{};
double ave_grades[30]{};
int sum(int a, int b, int c)
{
int d = 0;
d = a + b + c;
return d;
}
double average(double a, double b, double c)
{
double d = 0;
d = (a + b + c) / 3;
return d;
}
void as_sum()
{
for (int i = 0; i < 30; i++)
{
int j = 0; int a = j + 1; int b = j + 2;
sum_grades[i] = sum(grades[i][j], grades[i][a], grades[i][b]);
}
}
void as_average()
{
for (int i = 0; i < 30; i++)
{
int j = 0; int a = j + 1; int b = j + 2;
ave_grades[i] = average(grades[i][j], grades[i][a], grades[i][b]);
}
}
这一部分代码是分成三个部分 ,第一步创建用来装载总成绩与平均成绩的数组,第二部分是编写计算总成绩与平均成绩的函数,第三部分是利用第二部分编写的函数向总成绩和平均成绩的数组中填充数据。
(2)冒泡排序+排名方法
void bubble()
{
for (int i = 1; i < (sizeof(grades) / sizeof(grades[0])); i++)
{
int work = 1;
for (int j = 0; j < (sizeof(grades) / sizeof(grades[0])- i); j++)
{
if (sum_grades[j] > sum_grades[j + 1])
{
int temp = sum_grades[j];
sum_grades[j] = sum_grades[j + 1];
sum_grades[j+1] = temp;
work = 0;
}
}
if (work)break;
}
}
先把冒泡排序的函数摆在这里,一会儿会用到
void rank_self()
{
int b = 0;
cout << "RANK" << "\t" << "ID" << "\t" << endl;
int newself[30]{ };
for (int a = 0; a < 30; a++)
{
newself[a] = sum_grades[b];
b++;
}
bubble();
int c = 0;
for (int e = 0; e < 30; e++)
{
int d = 0;
for (; c < 30;)
{
if (newself[c] == sum_grades[d])
{
int rk = 30 - d;
cout << rk << "\t" << c+1 << endl;
break;
}
d++;
}
c++;
}
}
这一段函数是我想分享的方法,题目要求是计算学生成绩的排名,但是冒泡排序会把学生的成绩交换。由于我这时候没有学到数据结构,所以它交换的也只有总成绩,不能和学号一起被交换,所以我用了如下方法:
第1步、创建一个新的数组
第2步、将每一个学生的总成绩按顺序赋给这个新的数组
第3步、将原数组冒泡排序,得到的结果就是最大的数字(总成绩)在原数组的最底部,即sum_grades[29]到sum_grades[0]逐渐递减。
第4步、将新数组(newself[a])每一个数都和经过冒泡排序的原数组的所有数比较,如果新数组其中一个数字(此时新数组下标为c)和原数组的一个数字相等(此时原数组下标为d),将c+1作为学生的学号,因为sum_grades[29]到sum_grades[0]逐渐递减,所以30-d才是排名。
第5步、可以输出排名和学号啦!
(3)打印成绩表
void form()
{
cout << "Students' transcripts are as follows" << endl;
cout << "ID" << "\t" << "MT" << "\t" << "EN" << "\t" << "PH" << "\t" << "SUM" << "\t" << "AVE" << endl;
for (int i = 0; i < 30; i++)
{
int j = 0;
cout << i + 1 << "\t" << grades[i][j] << "\t" << grades[i][j + 1] << "\t" << grades[i][j + 2] << "\t" << sum_grades[i] << "\t" << ave_grades[i] << endl;
}
}
这一部分是用制表符+数组+循环实现的,就不详细说啦。
不过还是要说下,因为这个时候还没学数据结构所以还是用的数组下标代替学号的~
(4)输入学号,查出排名及成绩
void look_up()
{
int id = 0;
cout << "Please input id:";
cin >> id;
for (int d = 0; d < 30; d++)
{
if (newself[id-1] == sum_grades[d])
{
int rk = 30 - d;
cout << "The rank of this id is:" << rk << endl << "The grades of this id is:" << newself[id];
break;
}
}
}
这里需要说明的是,我们之前用的是学生总成绩的数组下标+1来代表学生的id的,所以输入id检索时我们也应该用id-1来代表数组下标,至于输出排名的方法则需参考(2)中提到的内容。
最后附上完整的代码,如有错误或者可以优化的地方,欢迎在评论区提出,谢谢啦🙏。
#include <iostream>
#include<ctime>
#include<stdlib.h>
using namespace std;
int sum(int, int, int);
double average(double, double, double);
void as_sum();
void as_average();
void as_grades();
int grades[30][3]{};
int sum_grades[30]{};
double ave_grades[30]{};
int newself[30]{ };
void form();
void rank_self();
void look_up();
int main()
{
as_grades();
as_sum();
as_average();
rank_self();
form();
look_up();
}
void as_grades()
{
srand((unsigned)time(NULL));
for (int i = 0; i < 30; i++)
{
for (int j = 0; j < 3; j++)
{
grades[i][j] = rand() % (100 - 60 + 1) + 60;
}
}
}
int sum(int a, int b, int c)
{
int d = 0;
d = a + b + c;
return d;
}
double average(double a, double b, double c)
{
double d = 0;
d = (a + b + c) / 3;
return d;
}
void as_sum()
{
for (int i = 0; i < 30; i++)
{
int j = 0; int a = j + 1; int b = j + 2;
sum_grades[i] = sum(grades[i][j], grades[i][a], grades[i][b]);
}
}
void as_average()
{
for (int i = 0; i < 30; i++)
{
int j = 0; int a = j + 1; int b = j + 2;
ave_grades[i] = average(grades[i][j], grades[i][a], grades[i][b]);
}
}
void bubble()
{
for (int i = 1; i < (sizeof(grades) / sizeof(grades[0])); i++)
{
int work = 1;
for (int j = 0; j < (sizeof(grades) / sizeof(grades[0])- i); j++)
{
if (sum_grades[j] > sum_grades[j + 1])
{
int temp = sum_grades[j];
sum_grades[j] = sum_grades[j + 1];
sum_grades[j+1] = temp;
work = 0;
}
}
if (work)break;
}
}
void form()
{
cout << "Students' transcripts are as follows" << endl;
cout << "ID" << "\t" << "MT" << "\t" << "EN" << "\t" << "PH" << "\t" << "SUM" << "\t" << "AVE" << endl;
for (int i = 0; i < 30; i++)
{
int j = 0;
cout << i + 1 << "\t" << grades[i][j] << "\t" << grades[i][j + 1] << "\t" << grades[i][j + 2] << "\t" << sum_grades[i] << "\t" << ave_grades[i] << endl;
}
}
void rank_self()
{
int b = 0;
cout << "RANK" << "\t" << "ID" << "\t" << endl;
for (int a = 0; a < 30; a++)
{
newself[a] = sum_grades[b];
b++;
}
bubble();
int c = 0;
for (int e = 0; e < 30; e++)
{
int d = 0;
for (; c < 30;)
{
if (newself[c] == sum_grades[d])
{
int rk = 30 - d;
cout << rk << "\t" << c +1<< endl;
break;
}
d++;
}
c++;
}
}
void look_up()
{
int id = 0;
cout << "Please input id:";
cin >> id;
for (int d = 0; d < 30; d++)
{
if (newself[id-1] == sum_grades[d])
{
int rk = 30 - d;
cout << "The rank of this id is:" << rk << endl << "The grades of this id is:" << newself[id];
break;
}
}
}