C++ sort比较函数的写法,最全面的总结

刷题的时候经常会遇到需要自己写一个sort比较函数,如果不知道怎么写比较函数那就算你知道其中的算法逻辑也做不出题目,下面介绍一下几种自定义的比较方法。

前置条件

  1. 注意C++sort是在algorithm这个包里的,注意include这个包
  2. sort的模板在下面:注意只能对RandomAccessIterator 进行排序!!什么是RandomAccessIterator ?如果需要详细的解释参看:RandomAccessIterator cppreference,简单说就是能够以任意的偏移进行访问的迭代器!如果不支持这样的是不能够用sort进行排序的!

Random-access iterators are iterators that can be used to access elements at an arbitrary offset position relative to the element they point to, offering the same functionality as pointers.

  1. 举个例子,map里面的迭代器是Bidirectional iterators,只能支持迭代器++,- -不支持+n这样的任意偏移,就不能够使用sort进行排序

  2. vector, deque支持RandomAccessIterator ,list, map, multimap, set and multiset只支持bidirectional iterators!

用法

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);

也就是有两种,一种是采用不写比较函数,另外一种是自定义比较函数。
注意:无论哪种前两个参数都是RandomAccessIterator,也就是不能直接传变量进去,必须是传入相应的迭代器,这是新手一开始非常容易犯的错误。

Binary function that accepts two elements in the range as arguments, and returns a value convertible to bool. The value returned indicates whether the element passed as first argument is considered to go before the second in the specific strict weak ordering it defines.
The function shall not modify any of its arguments.
This can either be a function pointer or a function object.

第1种:直接写比较函数

bool myfunction (int i,int j) {
    
     return (i<j); }

注意:这种比较函数必须写在类外部(全局区域)或声明为静态函数!(我听说是因为如果是作为一个成员函数,默认拥有一个this指针,和sort函数需要的函数对象类型不一样)。

第2种:定义一个结构体,构造一个函数对象(function object)也就是对运算符()进行重载,这就是相当于构造了一个函数对象

struct myclass {
    
    
  bool operator() (int i,int j) {
    
     return (i<j);}
} myobject;

第3种:采用lambada函数

对于简单的函数比较,可以采用C++11的新特性lambada函数

sort(msVector.begin(), msVector.end(), [](const MyStruct& ms1, const MyStruct& ms2){
    
    
    return ms1.weight < ms2.weight;
});

可以参考:https://www.cnblogs.com/DswCnblog/p/5629165.html

第4种:采用默认的less和greater

其实less和greater都是函数对象,即Function object,什么是function object?

Generically, function objects are instances of a class with member function operator() defined. This member function allows the object to be used with the same syntax as a function call.

可以看一下less的模板:

template <class T> struct less {
    
    
  bool operator() (const T& x, const T& y) const {
    
    return x<y;}
  typedef T first_argument_type;
  typedef T second_argument_type;
  typedef bool result_type;
};

可以看出来实际上less也是重载了一个()运算符,注意less是表示第一个元素比第二个元素小,其实就是升序排列
举例:

// less example
#include <iostream>     // std::cout
#include <functional>   // std::less
#include <algorithm>    // std::sort, std::includes

int main () {
    
    
  int foo[]={
    
    10,20,5,15,25};
  int bar[]={
    
    15,10,20};
  std::sort (foo, foo+5, std::less<int>());  // 5 10 15 20 25
  std::sort (bar, bar+3, std::less<int>());  //   10 15 20
  if (std::includes (foo, foo+5, bar, bar+3, std::less<int>()))
    std::cout << "foo includes bar.\n";
  return 0;
}

同样的,greater就表示降序排列,这是他的模板和应用示例。
模板:

template <class T> struct greater {
    
    
  bool operator() (const T& x, const T& y) const {
    
    return x>y;}
  typedef T first_argument_type;
  typedef T second_argument_type;
  typedef bool result_type;
};

示例:

// greater example
#include <iostream>     // std::cout
#include <functional>   // std::greater
#include <algorithm>    // std::sort

int main () {
    
    
  int numbers[]={
    
    20,40,50,10,30};
  std::sort (numbers, numbers+5, std::greater<int>());
  for (int i=0; i<5; i++)
    std::cout << numbers[i] << ' ';
  std::cout << '\n';
  return 0;
}

我个人建议还是采用第一种和第二种,第四种的方法,相对直观,如果还有其他方法也欢迎讨论。

猜你喜欢

转载自blog.csdn.net/Sansipi/article/details/127019948