输入学生个数以及每个学生的姓名和3门课程成绩:输出不及格学生的信息;按平均成绩排序,从高到低输出学生信息
要点
-
按平均成绩排序等价于按总分排序(只看最后结果不需要求平均成绩或者总分)
-
结构体排序,没有必要交换整个结构体,只需要另外开辟一个下标数组,根据所需对下标排序,最后按这个次序从原来表中读出即可,注意cmp中传入的是order[j],order[j+1]映射关系:
j->order[j]->structA[order[j]] -
统计是否不及格在读入数据时即可执行
-
从文件读入结构体,直接调用引用即可temp.xxx,文件用完要close,读文件是ios::in
-
printf_s在格式处理上优势明显
-
for(auto avr : container){ 、、、、了解一下}
-
一行函数可以让代码容易阅读(目的在函数名中得到了明确解释)
#include <iostream>
#include<algorithm>
#include<vector>
#include<fstream>
using namespace std;
#define see(x) cout<<x<<endl
typedef struct student {
char name[20];
int x1, x2, x3;
bool Failed;
}Stu;
class Sol
{
public:
//Sol() {}
Sol()
{
init();
}
~Sol() {
}
void init() {
readInfo();
sortByAvg();
}
void readInfo() {
//"C:\\Users\\dell\\source\\repos\\find_ci_xu\\Main\\test.txt"
fstream fin("test.txt", ios::in);
int num;
fin >> num;
Stu temp;
while (num--) {
fin >> temp.name >> temp.x1 >> temp.x2 >> temp.x3;
temp.Failed = isFailed(temp);
m_stus.push_back(temp);
}
fin.close();
}
bool isFailed(Stu& stu) {
return stu.x1 < 60 || stu.x2 < 60 || stu.x3 < 60;
}
void sortByAvg() {
int size = m_stus.size();
for (int i = 0; i < size; i++) {
m_sortByAvg.push_back(i);
}
for (int i = 0; i < size; i++) {
bool hasChange = false;
for (int j = 0; j + 1 < size; j++) {
if (cmp(m_sortByAvg[j], m_sortByAvg[j + 1])) {
swap(m_sortByAvg[j], m_sortByAvg[j + 1]);
hasChange = true;
}
}
if (!hasChange) break;
}
//sort(m_sortByAvg.begin(), m_sortByAvg.end(), cmp);
}
bool cmp(int i, int j) {
return getSum(i) < getSum(j);
}
int getSum(int i) {
return m_stus[i].x1 + m_stus[i].x2 + m_stus[i].x3;
}
void showAns() {
showFailedStu();
showSortByAvg();
}
void showFailedStu() {
cout << "failed student:" << endl;
for (auto t : m_stus)
{
if (t.Failed) {
showStu(t);
}
}
}
void showSortByAvg() {
cout << "sort By avg_scorces:" << endl;
int level = 1;
for (int i : m_sortByAvg) {
printf_s("[%d]", level++);
showStu(m_stus[i]);
}
}
void showStu(Stu &s) {
printf_s("name: %10s %3d %3d %3d\n", s.name, s.x1, s.x2, s.x3);
}
private:
vector<Stu> m_stus;
vector<int> m_sortByAvg;
};
int main()
{
Sol test;
test.showAns();
system("pause");
return 0;
}
执行模式总结
-
原则一,不返回临时变量的引用
-
原则二,函数实际平行(地位相当的子函数)的逻辑块不超过七行
-
只做一件事,不要修改多余的东西
-
命名方式动词加名词 如 getName() sortStusTable()
-
修改对象的状态,转化为修改对象的属性,即传入引用(参数不超过三个,多了考虑建类)
-
减少重复,逻辑上,表达上的冗余
-
原则三,定义变量名能表达明确的意图(具体是什么空间的谁以某种方式做了什么)
-
全局变量:G开头,全部要大写 如 const int G_MAX_STUS=101010;
-
类的成员:m开头,使用小写 如 string m_addrPhoneNumber;
-
临时变量:_开头,首字母大写如int _TempScore;放在函数的开头
//names
typedef struct student {
char name[16];
int scores1, scores2;
int failed;
int getSum() {
return scores1 + scores2; }
void showInfo() {
printf_s("name:%16s |%3d|%3d|\n", name, scores1, scores2);
}
}Stu;
typedef vector<Stu> Stable;// StudentsTable
typedef vector<int> Sorder;// sortedOrder
void showSortedAns() {
Stable stus;
Sorder order;
readStus(stus);
sortByAvg(stus, order);
printAns(stus, order);
}
void readStus(Stable &table) {
fstream fin("data.txt", ios::in);
//readInfo to table
fin.close();
}
void sortByAvg(Stable &table, Sorder &order) {
int size = table.size();
init(order,size);
for (int round = 0; round< size; round++) {
bool update = false;
for (int ptr = 0; ptr + 1 < size; ptr++) {
if (cmp(order[ptr], order[ptr + 1],table)) {
swap(order[ptr], order[ptr + 1]);
update = true;
}
}
if (!update) break;
}
}
void init(Sorder &order,int n) {
order.clear();
for (int i = 0; i < n; i++) {
order.push_back(i);
}
}
bool cmp(int i, int j, Stable &table) {
return table[i].getSum() < table[j].getSum();
}
void printAns( Stable &table,Sorder &order) {
for (int p : order) {
table[p].showInfo();
}
cout << endl;
}