關於字符串中字符按ascii碼值排序的一些疑問

function templateios

<algorithm>c++

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).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,4

    return 0;
}

 

總結:

一. qsort函數:
原 型: void qsort(void *base, int nelem, int width, int (*fcmp)(const void *,const void *));
功 能: 使用快速排序例程進行排序 參 數:

  1. 待排序數組首地址
  2. 數組中待排序元素數量
  3. 各元素的佔用空間大小
  4. 指向函數的指針,用於肯定排序的順序

    說 明: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比較函數中都是傳地址或傳引用,而不是傳值的參數傳遞方式,或者說它們都須要對待排序的數組進行修改。

==============

image

相關文章
相關標籤/搜索