关于字符串中字符按ascii码值排序的一些疑问

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,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指明元素的大小事怎么比较的。

二、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

 

转载于:https://my.oschina.net/ray1421/blog/690727

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值