程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> [Jobdu OJ] 1023 EXCEL排序

[Jobdu OJ] 1023 EXCEL排序

編輯:C++入門知識

題目描述:
Excel可以對一組紀錄按任意指定列排序。現請你編寫程序實現類似功能。 對每個測試用例,首先輸出1行“Case i:”,其中 i 是測試用例的編號(從1開始)。隨後在 N 行中輸出按要求排序後的結果,即:當 C=1 時,按學號遞增排序;當 C=2時,按姓名的非遞減字典序排序;當 C=3
時,按成績的非遞減排序。當若干學生具有相同姓名或者相同成績時,則按他們的學號遞增排序。
輸入:

測試輸入包含若干測試用例。每個測試用例的第1行包含兩個整數 N (N<=100000) 和 C,其中 N 是紀錄的條數,C 是指定排序的列號。以下有N行,每行包含一條學生紀錄。每條學生紀錄由學號(6位數字,同組測試中沒有重復的學號)、姓名(不超過8位且不包含空格的字符串)、成績(閉區間[0, 100]內的整數)組成,每個項目間用1個空格隔開。當讀到 N=0 時,全部輸入結束,相應的結果不要輸出。

輸出:
對每個測試用例,首先輸出1行“Case i:”,其中 i 是測試用例的編號(從1開始)。隨後在 N 行中輸出按要求排序後的結果,即:當 C=1 時,按學號遞增排序;當 C=2時,按姓名的非遞減字典序排序;當 C=3
時,按成績的非遞減排序。當若干學生具有相同姓名或者相同成績時,則按他們的學號遞增排序。
樣例輸入:
3 1
000007 James 85
000010 Amy 90
000001 Zoe 60
4 2
000007 James 85
000010 Amy 90
000001 Zoe 60
000002 James 98
4 3
000007 James 85
000010 Amy 90
000001 Zoe 60
000002 James 90
0 0
樣例輸出:
Case 1:
000001 Zoe 60
000007 James 85
000010 Amy 90
Case 2:
000010 Amy 90
000002 James 98
000007 James 85
000001 Zoe 60
Case 3:
000001 Zoe 60
000007 James 85
000002 James 90
000010 Amy 90

問題解析:這道題就是對一個給定的數據集合進行排序,該數據集合包含三個字段,根據給定的第二個參數,對不同的字段進行排序。首先,如何存儲這些數據,可以用一個結構體保存一個記錄,然後用一個容器保存一次排序的集合。其次,如何對某個字段進行排序,在標准庫中有sort算法,但是,它用的是數據成員的operator<來進行比較的,因此,要實現某個字段的比較,就要另外構造比較函數,這裡使用函數對象。

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

struct student {
	string id;
	string name;
	unsigned int remark;
};

ostream& operator<<(ostream &out, student stu)
{
	out << stu.id << " " << stu.name << " " << stu.remark;
	return out;
}

struct compare_id {
	bool operator()(student x, student y)
	{
		return x.id < y.id;
	}
};

struct compare_name {
	bool operator()(student x, student y)
	{
		if(x.name == y.name) {
			return x.id < y.id;
		}
		else {
			return x.name < y.name;
		}
	}
};

struct compare_remark {
	bool operator()(student x, student y)
	{
		if(x.remark == y.remark) {
			return x.id < y.id;
		}
		else {
			return x.remark < y.remark;
		}
	}
};

int main()
{
	unsigned long records = 0;
	unsigned int c = 0;
	unsigned int cnt = 0;
	vector svec;
	student stu;
	int index = 0;

    ifstream cin("luo.txt");
	while(cin >> records >> c, records && c) {
		svec.resize(records);
		index = 0;
		while(index < records) {
			cin >> svec[index].id >> svec[index].name >> svec[index].remark;
			++index;
		}
		switch(c) {
			case 1:
			    sort(svec.begin(), svec.end(), compare_id());
			    break;
			case 2:
			    sort(svec.begin(), svec.end(), compare_name());
			    break;
			case 3:
			    sort(svec.begin(), svec.end(), compare_remark());
			    break;
			default:
			    break;
		}
		cout << "Case " << ++cnt << ":" << endl;
		copy(svec.begin(), svec.end(), ostream_iterator(cout, "\n"));
		svec.clear();
	}

	return 0;
}

這裡用到了C++中的幾點知識:

(1)函數的重載:operator<<;

(2)函數對象;

(3)algorithm中的sort。

注意:這題雖然很簡單,但是,要注意的問題也很多:
(1)學號字段雖然可以存儲在unsigned int中,但是,如果使用unsigned int會WA;
(2)雖然vector的好處是用戶可以隨意添加元素,但是這裡不能自由地進行push_back,否則會WA,而應該先使用resize將容器的大小變成所需要的大小,然後再往裡面放置元素,因此,這裡使用new也是很方便的;
(3)輸出結果時Case後面那個整數是測試用例的編號,而不是排序方式。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved