例题:http://acm.hdu.edu.cn/showproblem.php?pid=1862
杭电1862:EXCEL排序
题目中文题目,就不用再去翻译了,只是说明一下,题目的大意
题目是说像excel那样进行排序,如果不知道也没关系,题目已经说明了具体的排序规则如下:
随后在 N 行中输出按要求排序后的结果,即:当 C=1 时,按学号递增排序;当 C=2时,按姓名的非递减字典序排序;当 C=3 时,按成绩的非递减排序。当若干学生具有相同姓名或者相同成绩时,则按他们的学号递增排序。
数据组数有较多,用其他排序方法,在时间上不能够得到保证,并且涉及到多级排序,所以,用函数库自带的qsort函数还是较为方便的。
具体关于qsort资料整理如下:
七种qsort排序方法<本文中排序都是采用的从小到大排序>
一、对int类型数组排序
C++代码
- int num[100];
Sample:
- int cmp( const void *a , const void *b )
- {
- return *(int *)a – *(int *)b;
- }
- qsort(num,100,sizeof(num[0]),cmp);
二、对char类型数组排序(同int类型)
C++代码
- char word[100];
Sample:
- int cmp(const void *a ,const void *b)
- {
- return *(char *)a – *(char*)b;
- }
- qsort(word,100,sizeof(word[0]),cmp)
三、对double类型数组排序(特别要注意)
C++代码
- double in[100];
- int cmp(const void *a ,const void *b)
- {
- return *(double *)a > *(double *)b ? 1 : -1;
- }qsort(in,100,sizeof(in[0]),cmp);
四、对结构体一级排序
C++代码
- struct In{
- double data;
- int other;
- }s[100]
- //按照data的值从小到大将结构体排序,关于结构体内的排序关键数据data的类型可以很多种,参考上面的例子写
- int cmp(const void *a ,constvoid *b)
- {
- return (*(In *)a).data >(*(In *)b).data ?1 : -1;
- }
- qsort(s,100,sizeof(s[0]),cmp);
五、对结构体二级排序
C++代码
1. typedef struct In{
2. int x;int y;
3. }s[100];
4. //按照x从小到大排序,当x相等时按照y从大到小排序
5. int cmp(constvoid *a , const void *b)
6. {
7. In *c = (In *)a;
8. In *d = (In *)b;
9. if(c->x != d->x)return c->x – d->x;
10. elsereturn d->y – c->y;
11. }
12. qsort(s,100,sizeof(s[0]),cmp);
六、对字符串进行排序
C++代码
- struct In{
- int data; char str[100];
- }s[100];
- //按照结构体中字符串str的字典顺序排序
- int cmp( const void *a , const void *b )
- {
- returnstrcmp( (*(In *)a).str ,(*(In *)b).str);
- }
- qsort(s,100,sizeof(s[0]),cmp);
七、计算几何中求凸包的cmp
C++代码
- int cmp(constvoid *a,constvoid *b)
- //重点cmp函数,把除了1点外的所有点,旋转角度排序
- {
- struct point *c=(point *)a;
- struct point *d=(point *)b;
- if( calc(*c,*d,p[1]) < 0) return 1;
- elseif( !calc(*c,*d,p[1])
- && dis(c->x,c->y,p[1].x,p[1].y) < dis(d->x,d->y,p[1].x,p[1].y))
- //如果在一条直线上,则把远的放在前面
- return 1; elsereturn -1;
- }
PS: 其中的qsort函数包含在的头文件里,strcmp包含在的头文件里
主要的理解的地方就是:
五、对结构体二级排序
C++代码
1. typedef struct In{
2. int x;int y;
3. }s[100];
4. //按照x从小到大排序,当x相等时按照y从大到小排序
5. int cmp(cons tvoid *a ,const void *b)
6. {
7. In *c = (In *)a; //定义另一个指针以此代替两个原指针,再进行比较
8. In *d = (In *)b;
9. if(c->x != d->x)return c->x – d->x; //如果相等的话就进行另一项排序,只不过是排序的对象发生变化,
10. elsereturn d->y – c->y; // 根据排序的方式(降序、升序)调整其先后位置
11. }
12. qsort(s,100,sizeof(s[0]),cmp); // 此函数包含在头文件stdlib.h中
s为要排序的数组名,接着是数组长度,然后是单个元素的长度,最后是排序方式的函数(由自己编写)
在编写比较方式函数的时候,要注意指针的运用,以此提高简洁性同时应该注意多级排序时的先后顺序
最后在此附上题目代码:(仅供参考)
# include<stdio.h>
# include<stdlib.h>
# define M 100000
# include<string.h>
struct ln{
int xuehao;
char name[10];
int score;
};
struct ln a[M+10];
int cmpx(const void *a,const void *b){ //按学号排序
return (*(ln*)a).xuehao-(*(ln*)b).xuehao;
}
int cmpn(const void *a,const void *b){ // 先按按名字的字典排序再按序号排序
ln *c=(ln*)a;
ln *d=(ln *)b;
if(!strcmp(c->name,d->name)) //此处需注意 指针
return c->xuehao-d->xuehao;
else
return strcmp(c->name,d->name);
}
int cmps(const void *a,const void *b){ // 先按成绩排序再按学号排序
ln *c=(ln*)a;
ln *d=(ln *)b;
if(c->score==d->score)
return c->xuehao-d->xuehao;
else
return c->score-d->score;
}
int main(){
int n,c;
int i;
int t=0;
while(scanf("%d%d",&n,&c)&&n){
t++;
for(i=0;i<n;i++){ //将学生信息以此输入
scanf("%d%s%d",&a[i].xuehao,a[i].name,&a[i].score);
}
if(c==1) //选择排序方式
qsort(a,n,sizeof(a[0]),cmpx);
if(c==2)
qsort(a,n,sizeof(a[0]),cmpn);
if(c==3)
qsort(a,n,sizeof(a[0]),cmps);
printf("Case %d:\n",t);
for(i=0;i<n;i++){ //对结果输出
printf("%06d %s %d\n",a[i].xuehao,a[i].name,a[i].score);
}
}
return 0;
}
整理人:李富昌
整理时间:20140807