1.综述
这是一个基础问题,也就是说已经被研究透了。
现行环境下最方便的方案还是使用库函数strcmp+qsort
2.strcmp()用法
定义在<string.h> / <cstring>
输入只能是c中的char[]数组,或者c++中的string;
效果为比较两个字符串的字典序大小,如"a"<"A","a123"<"a145";
返回值为负数/0/正数;
负数表示小于;
3.strcmp函数实现方案
①形式简单易懂,输出值-1/0/1更优美
#include <string.h>
int(strap)(const char *sl,const char *s2)
{
/*compare unsigned char sl[],s2[]*/
for(;*sl==*s2;++sl,++s2)
if(*sl=='\0')
return(0);
return((*(unsignedchar*)sl<*(unsignedchar*)s2)?-1:+1);
}
如果不对输出结果进行 01修饰
int strcmp(const char *str1,const char *str2)
{
while(*str1 == *str2)
{
if(*str1 == '\0')
return0;
str1++; str2++;
}
return *str1 - *str2;
}
②更简洁效率,缺点是输出值可以为不确定的负数/正数
int strcmp(const char * src, const char * dst)
//字典序比较两字符串大小
{
int ret = 0 ;
while(!(ret=*src-*dst)&&*dst) //相等且没有结束
++src; ++dst;
return( ret );
}
④qsort()函数用法
用以对数组进行排序
void qsort (void* base, size_t num, size_t size,
int (*compar)(const void*,const void*));
这个函数的优点在于,其对于顺序的“价值定义”是不确定的。
可以任意给定cmp函数来确定排序的依赖主体。
参数1,开始排序的地址,easy模式下可以采用数组名代替;
参数2 参与排序元素个数(size_t);
参数3 单个元素大小 (size_t);
参数4 cmp函数,确定排序时的价值取向;
qsort会不断调用cmp来比较数组元素的大小。
其中cmp函数在官网手册中特别说明如下
------
return value | meaning |
---|---|
<0 | The element pointed to by p1 goes before the element pointed to by p2 |
0 | The element pointed to by p1 is equivalent to the element pointed to by p2 |
>0 | The element pointed to by p1 goes after the element pointed to by p2 |
可以任意编纂cmp函数的逻辑,只要返回值<0,则p1会被置于p2前。
同时也实现了,排序逻辑与排序对象的抽象分离。
关于qsort源码请看下面。
两篇内容相近,对照着看理解更好。
https://blog.csdn.net/u011822516/article/details/17059693
https://blog.csdn.net/gen_ye/article/details/52880461
本人阅读以上2篇文章后改写的小作业:
https://blog.csdn.net/w55100/article/details/80516573
5.一个程序案例(strcmp+qsort+结构体)
描述
给出班里某门课程的成绩单,请你按成绩从高到低对成绩单排序输出,如果有相同分数则名字字典序小的在前。
输入
第一行为n (0 < n < 20),表示班里的学生数目;
接下来的n行,每行为每个学生的名字和他的成绩, 中间用单个空格隔开。名字只包含字母且长度不超过20,成绩为一个不大于100的非负整数。
输出
把成绩单按分数从高到低的顺序进行排序并输出,每行包含名字和分数两项,之间有一个空格。
实例
#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;
struct student{
char name[20];
int score;
};
//复杂的排序逻辑合并到一个cmp函数内
int cmp(const void *a,const void *b){
//特别注意,此处形参列表必须使用const void *形式,不然会报错
student *p1 = (student*)a;
student *p2 = (student*)b;
if( p1->score== p2->score){
//成绩相同时,比较结构体的name大小
return strcmp( p1->name, p2->name);
}
else{
return p2->score - p1->score; //成绩需要高到低排序
}
}
int main(){
int n;
int i;
struct student stus[20];
//输入
cin>>n;
for(i= 0;i<n;i++){
cin>>stus[i].name>>stus[i].score;
}
//排序
qsort(stus,20,sizeof(student),cmp);
//输出
for(i= 0;i<n;i++){
cout<<stus[i].name<<" "<<stus[i].score<<endl;
}
system("pause");
return 0;
}
其他参考
http://www.cplusplus.com/reference/cstdlib/qsort/
https://blog.csdn.net/eapid/article/details/1552310