混淆使用 std::less 和 std::greater 与 std::sort

Posted

技术标签:

【中文标题】混淆使用 std::less 和 std::greater 与 std::sort【英文标题】:confusion about using std::less and std::greater with std::sort 【发布时间】:2013-01-27 12:27:15 【问题描述】:

在C语言中,sort通常实现如下:

#include <stdio.h>

void Sort( int* arr, int n, bool(*cmp)(int,int) )

    for( int i=0; i<n-1; i++ )
    
        for( int j=i+1; j<n; j++ )
        
            if( cmp(arr[i], arr[j]) )
                swap( arr[i], arr[j] );
        
    


int ascending( int a, int b )  return a > b;     // greater
int descending( int a, int b )  return a < b;    // less

void main()

    int arr[10] =  1,3,5,7,9,2,4,6,8,10 ;

    // ascending
    Sort( arr, 10, ascending );
    for( int i=0; i<10; i++ )
        printf( "%d ", arr[i] );

    printf( "\n" );


    // descending
    Sort( arr, 10, descending );
    for( int i=0; i<10; i++ )
        printf( "%d ", arr[i] );

    printf( "\n" );

所以我写了一些源代码,如下例所示,期望得到相同的结果:

#include <iostream>
#include <algorithm>    // for sort
#include <functional>   // for less & greater
using namespace std;

bool gt( int a, int b )  return a > b;    // greater
bool ls( int a, int b )  return a < b;    // less

void main()

    int x[10] =  1,3,5,7,9,2,4,6,8,10 ;

    // ascending but descending
    sort( x, x+10, gt );
    for( int i=0; i<10; i++ )
        cout << x[i] << " ";

    cout << endl;

    // descending but ascending
    sort( x, x+10, ls );
    for( int i=0; i<10; i++ )
        cout << x[i] << " ";

    cout << endl;


    greater<int> g; // a > b
    less<int> l;    // a < b

    // ascending but descending
    sort( x, x+10, g );
    for( int i=0; i<10; i++ )
        cout << x[i] << " ";

    cout << endl;

    // descending but ascending
    sort( x, x+10, l );
    for( int i=0; i<10; i++ )
        cout << x[i] << " ";

    cout << endl;

但我的预期不正确。

为什么 STL 中的排序不像 C 中的排序那样工作?

【问题讨论】:

【参考方案1】:

std::sort 默认按升序排序。如果您正在寻找降序,这里的诀窍是:

int x[10] =  1,3,5,7,9,2,4,6,8,10 ;
std::vector<int> vec(x, x+10);          // construct std::vector object
std::sort(vec.rbegin(),vec.rend());     // sort it in reverse manner

这样,您明确地说std::sort 应该将您的数组视为它的结尾是它的开头,反之亦然,这导致您的数组按降序排序。 Here's the full example.


如果你想使用std::lessstd::greater,那么它可能看起来像这样:

int x[10] =  1,3,5,7,9,2,4,6,8,10 ;
std::sort(x, x + 10, std::less<int>());     // for ascending order
std::sort(x, x + 10, std::greater<int>());  // for descending order

第二种解决方案的完整示例是here。

【讨论】:

【参考方案2】:

std::sort 的行为是这样的,因为它基于 strict weak ordering 的概念,它(通常)根据 &lt; 运算符定义。

关于你的问题;目前似乎是“我编写了一个与std::sort 行为不同的C 函数。为什么不同?”。答案是:因为你写了一个不同的函数!

【讨论】:

以上是关于混淆使用 std::less 和 std::greater 与 std::sort的主要内容,如果未能解决你的问题,请参考以下文章

如何在不重载 `operator()`、`std::less`、`std::greater` 的情况下为`std::multiset` 提供自定义比较器?

我的C/C++语言学习进阶之旅解决使用algorithm库里面的sort函数的时候,编译报错:未能使函数模板“unknown-type std::less<void>::operator ()(代码片

我的C/C++语言学习进阶之旅解决使用algorithm库里面的sort函数的时候,编译报错:未能使函数模板“unknown-type std::less<void>::operator ()(代码片

map排序

C++ std::set<,> operator怎么用

vc++ windbg dump 调试 疑问!