2020秋季第 1 周训练 习题笔记
D-EXCEL排序
Excel可以对一组纪录按任意指定列排序。现请你编写程序实现类似功能。
Input
测试输入包含若干测试用例。每个测试用例的第1行包含两个整数 N (<=100000) 和 C,其中 N 是纪录的条数,C 是指定排序的列号。以下有 N行,每行包含一条学生纪录。每条学生纪录由学号(6位数字,同组测试中没有重复的学号)、姓名(不超过8位且不包含空格的字符串)、成绩(闭区间[0, 100]内的整数)组成,每个项目间用1个空格隔开。当读到 N=0 时,全部输入结束,相应的结果不要输出。
Output
对每个测试用例,首先输出1行“Case i:”,其中 i 是测试用例的编号(从1开始)。随后在 N 行中输出按要求排序后的结果,即:当 C=1 时,按学号递增排序;当 C=2时,按姓名的非递减字典序排序;当 C=3
时,按成绩的非递减排序。当若干学生具有相同姓名或者相同成绩时,则按他们的学号递增排序。
Sample Input
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
Sample Output
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函数,sort函数是C++的排序方式的一种,需要用到的头文件是#include<algorithm>
,sort函数默认为升序排序,而且是左闭右开,所以调用的时候应当注意sort函数左边是首地址,右边是最后一位的地址+1。
int a[5]={1,2,3,4,5};
sort(a,a+5);
但是由于sort函数是默认升序排序,当sort函数默认升序排序的话,就是2个参数,但是如果要自定义升序和降序的话就要添加第三个函数,那么就要有两种方法:
第一种方法:加入一个比较函数cmp()
,然后使用sort(begin,end,cmp)
(结构体或者自定义排序规则,需要自定义cmp函数。
cmp函数的含义,如果返回值是 True,表示 要把 序列 (X,Y),X放Y前。
bool cmp(int &x,int &y){
return x>y;//意味着x>y的时候,把x放到y前,按大到小排序。 }
理解:sort默认是从小到大,所以在cmp如果还是要从小到大,那就a < b,返回值bool为true,不改变;而如果想要从大到小排,那么就要return a > b,因为默认a小于b,所以此时返回的bool就是false,要改变排序。
第二种方法:
第一种方法虽然实现了随意定义升序和降序,但是却需要加入比较函数,比较麻烦,第二种方法可以直接加入第三个参数来告诉函数是升序还是降序
从小到大排序:less<数据类型>()
从大到小排序:greater<数据类型>()
对于excel表格中的字符串大小比较,就可以调用cstring头函数中的strcmp函数,进行一位一位的大小比较,代码中的return strcmp(x.name,y.name)<0
就是说x.name<y.name
,如果符合那么返回真值,反之,就返回假值。
值得注意的是:对于学生的学号,我们也不必把它当成字符串处理,我们可以先把它当成整数型变量来处理,输出的时候用0n%来在最前面补全所有的0即可。
以下是源代码
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
struct stud
{
char name[10];
int score;
int num;
}a[100001];
int cmpnum(stud x,stud y){
return x.num<y.num;
}
int cmpscore(stud x,stud y){
if(x.score==y.score) return x.num<y.num;
else return x.score<y.score;
}
int cmpname(stud x,stud y){
if(strcmp(x.name,y.name)==0) return x.num<y.num;
else return strcmp(x.name,y.name)<0;
}
int main (){
int n=1,i=0,c,h=0;
while(cin>>n>>c&&n)
{
h++;
for(int i=1;i<=n;i++){
scanf("%d %s %d",&a[i].num,&a[i].name,&a[i].score);}
if(c==1) sort(a+1,a+1+n,cmpnum);
else if(c==2) sort(a+1,a+1+n,cmpname);
else if(c==3) sort(a+1,a+1+n,cmpscore);
printf("Case %d:\n",h);
for(int i=1;i<=n;i++)
printf("%06d %s %d\n",a[i].num,a[i].name,a[i].score);
}
return 0;
}