曾经用到过一次快排,感觉代码量没有减小,反而比较函数有点难编,但是这种排序一般不会出错(前提是比较函数写对了),而且速度很快,熟练后其实还是非常好用的!
用到快排是因为我做到一个题,是uva的10420,题目为战利品清单,大致意思是要统计在名单上每个国家的女人名字出现了几次。开始以为要考虑去掉重名之类的(题目没有提重名一事),后来百度一下看网上有人说不用考虑重名,就没有考虑了。
我看了一下网上的代码,在比较函数那里都写错了,不知道是怎么过的都,给出一个AC了的版本,比较函数是先比较两个字符串的首字母,首字母相同再比较第二个字母,第三个等等.....我试过应该不能直接用strcmp函数,因为strcmp函数好像是要计算每个字母的ascii码后相加比较,所以如果两个字符串位数不同会影响结果。比如说China和England两个国家,按题目意思是应该China在前,England在后的(字典序),但是strcmp比较则是England在前了。
#include<iostream> #include<cstring> #include<string> #include<cstdlib> using namespace std; struct list { char country[20]; //char name[80]; int num; }; list data[2000]; int cmp_country(const void* a,const void* b) { int index=0; int lena=strlen(((list*)a)->country); int lenb=strlen(((list*)b)->country); int len=strlen(((list*)a)->country)<strlen(((list*)b)->country)?strlen(((list*)a)->country):strlen(((list*)b)->country); while(index!=len){ char cmp_a=((list*)a)->country[index]; char cmp_b=((list*)b)->country[index]; if (cmp_a!=cmp_b) return cmp_a<cmp_b?-1:1; index++; } if (lena==lenb) return 0; else if (lena>lenb) return 1; else return -1; } int main() { int n,counts=0; cin>>n; for (int i=0;i<n;i++) { char tmpcoun[20]; cin>>tmpcoun; char tmpname[80]; cin.getline(tmpname,80); bool flag=0; for (int j=0;j<counts;j++) { if (strcmp(tmpcoun,data[j].country)==0) { data[j].num++; flag=1; break; } } if (flag==0) { strcpy(data[counts].country,tmpcoun); data[counts++].num=1; } } qsort(data,counts,sizeof(data[0]),cmp_country); for (int i=0;i<counts;i++) { cout<<data[i].country<<" "<<data[i].num<<endl; } return 0; }