function template
<algorithm>
std::sort
default (1) | template <class RandomAccessIterator> void sort (RandomAccessIterator first, RandomAccessIterator last); |
---|---|
custom (2) | template <class RandomAccessIterator, class Compare> void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp); |
Sort elements in range
Sorts the elements in the range [first,last)
into ascending order.
The elements are compared using operator<
for the first version, and comp for the second.
Equivalent elements are not guaranteed to keep their original relative order (see stable_sort).
======================
如果用stl中的sort函数对字符串中的字符按ascii码值排序,一定不能按下面的方法
bool cmp(char& ch1,char& ch2){
return ch1<ch2;
}
char * str=new char[20];
strcpy(str, “hello world”);
sort(str,str+strlen(str),cmp);
===========
#include<iostream>
#include<string>
#include<algorithm> //for sort algorithm
#pragma warning(disable:4996) //只适用于windows平台,数字是编译时vs提示的数字。
#include<stdio.h>
#include<stdlib.h> //for qsort algorithm
using namespace std;
//第一个比第二个大,输出1,在内部进行交换;小输出0。如果想要降序的话,正好相反。
//在sort函数中使用,两个参数可能直接是待比较的元素的引用类型,而不必是指针。
bool cmp(char& ch1,char& ch2){ //&符号不能少,类似交换两个数的函数中的传值与传引用的原因。
return ch1>ch2; //降序
}
//在qsort方法中用,要求两个参数是const void*类型。
int compare(const void* ch1, const void* ch2){
// return (*(char*)ch1 > *(char*)ch2) ? 1 : 0;
return (*(char*)ch1 - *(char*)ch2; //这是更规范和简洁的写法。
}
int main(){
char strName[9];
int i;printf("Enter your family name: ");
scanf("%8s", strName); //可以实现和scanf_s相同的功能。
puts(strName);
//方法一,对输入字符串进行排序
string str;
cin >> str;
//cout << *str.end() << endl; error:str.end()返回值相当于null,不应该对其解引用。
cout << (int)*(str.end() - 1) << endl;//这里输出的是str的最后一个字符的ascii码值,注意string类型并不以'\0'结尾。如果输入的str是12345,则这里输出的应该是5的ascii码值,即0x35=53.
sort(str.begin(), str.end()); //如果是以char*作为参数,则得不到正确结果。
cout << str << endl;
//方法二,利用c语言中的stdlib.h中的qsort进行排序。
char* ch = new char[20];
cin >> ch;
//qsort(ch, sizeof(ch)-1, sizeof(char), compare); 第二个参数是比较的元素的个数,而对于一个char*来说它的sizeof求值的结果是一个指针的长度,在32位系统下是4。这里应该用的是strlen(ch),不需要减1,因为本身是不计入'\0'的。
//注意char ch[17];和char*在sizeof求值时的区别。
qsort(ch, strlen(ch), sizeof(char), compare);
puts(ch);//下面注意一个容易出错的地方。
char str123[] = "hello";
char str124[] = { '1', '2', '3'};
char* str125 = str124;
*(str125 + 3) = '5'; //可能会数组越界。报错。用数组访问内存时,相应的内存必须是你在程序里申请过的,不管是当前的指针申请的,还是程序里其他指针申请的。
*(str125 + 4) = '\0';
cout << sizeof(str123) << " " << strlen(str123) << endl; //结果6,5
//sizeof求数组的长度
cout << sizeof(&str124) << endl; //输出4
cout << sizeof(str124) << " " << strlen(str124) << endl; //输出3,4return 0;
}
总结:
一. qsort函数:
原 型: void qsort(void *base, int nelem, int width, int (*fcmp)(const void *,const void *));
功 能: 使用快速排序例程进行排序 参 数:
- 待排序数组首地址
- 数组中待排序元素数量
- 各元素的占用空间大小
指向函数的指针,用于确定排序的顺序
说 明:qsort函数是ANSI C标准中提供的,其声明在stdlib.h文件中,是根据二分法写的,其时间复杂度为n*log(n)。
qsort要求提供的函数是需要自己定义的一个比较函数,比较函数使得qsort通用性更好。有了比较函数qsort可以实现对数组、字符串、结构体等结构进行升序或降序排序。
如int cmp(const void *a, const void *b)中有两个元素作为参数(参数的格式不能变的。)返回一个int值,如果比较函数返回大于0,qsort就认为a > b,返回小于0,qsort就认为a < b。qsort知道元素的大小了,就可以把大的放前面去。如果你的比较函数返回本来应该是1的(即a > b),而却返回-1(小于0的数),那么qsort认为a < b,就把b放在前面去,但实际上是a > b的,所以就造成了降序排序的差别了。简单来说,比较函数的作用就是给qsort指明元素的大小事怎么比较的。二、sort和qsort比较:
1.cmp函数和qsort中cmp函数的不同int cmp(const int &a,const int &b) {
return a>b ;
}
sort中的cmp函数参数可以直接是参与比较的引用类型。
2.cmp函数比较时qsort用“-”减号,而sort用”>”.这也是一个重要的区别。 因为qsort比较函数的返回值要求是int类型,而sort函数的返回值要求是bool类型。
3.sort函数是c++中标准模板库的的函数,在qsort()上已经进行了优化,根据情况的不同可以采用不同的算法,所以较快。在同样的元素较多和同样的比较条件下,sort()的执行速度都比qsort()要快(因编译器而异)。另外,sort()是类属函数,可以用于比较任何容器,任何元素,任何条件。使用时需调用<algorithm> 头文件,并且指定using namespace std;
sort(begin(),end(),cmp);4. 如果能用sort尽量用sort,对于常见类型的升序排序,不需要自己编写cmp函数。只需要指定头指针,尾指针即可。尾指针的含义与迭代器中的end函数相同。即第二个参数所指向的元素不参加排序。即排序的区间是左闭右开。
如果想降序排列,可以使用自己编的cmp函数。
bool compare(int a,int b){
return a>b; //降序排列,如果改为return a<b,则为升序。这是默认的排序函数的写法。前面的数小。
//注:对于qsort,当a>b时,返回正数,是升序。与sort正好相反。
//bool类型,什么情况下等效为true,什么情况下等效为false;
}
无论是sort还是qsort比较函数中都是传地址或传引用,而不是传值的参数传递方式,或者说它们都需要对待排序的数组进行修改。
==============