精简原则:结构体之学生成绩排序

输入学生个数以及每个学生的姓名和3门课程成绩:输出不及格学生的信息;按平均成绩排序,从高到低输出学生信息

要点

  1. 按平均成绩排序等价于按总分排序(只看最后结果不需要求平均成绩或者总分)

  2. 结构体排序,没有必要交换整个结构体,只需要另外开辟一个下标数组,根据所需对下标排序,最后按这个次序从原来表中读出即可,注意cmp中传入的是order[j],order[j+1]映射关系:
    j->order[j]->structA[order[j]]

  3. 统计是否不及格在读入数据时即可执行

  4. 从文件读入结构体,直接调用引用即可temp.xxx,文件用完要close,读文件是ios::in

  5. printf_s在格式处理上优势明显

  6. for(auto avr : container){ 、、、、了解一下}

  7. 一行函数可以让代码容易阅读(目的在函数名中得到了明确解释)

#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;
}

猜你喜欢

转载自blog.csdn.net/qq_34890856/article/details/105880675
今日推荐