function templateios
<algorithm>c++
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).windows
======================數組
若是用stl中的sort函數對字符串中的字符按ascii碼值排序,必定不能按下面的方法dom
bool cmp(char& ch1,char& ch2){函數
return ch1<ch2;優化
}ui
char * str=new char[20];spa
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指明元素的大小事怎麼比較的。2、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比較函數中都是傳地址或傳引用,而不是傳值的參數傳遞方式,或者說它們都須要對待排序的數組進行修改。
==============