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

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

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在C语言中,结构体的构造函数并不像C++一样有专门的语法来定义。在C中,我们通常使用以下两种方式来实现结构体的构造函数: 1. 默认构造函数:在定义结构体时,可以不显式地写出构造函数,C语言会自动为结构体生成一个默认构造函数。例如,在定义结构体Node时,可以使用Node(){}的形式定义一个默认构造函数。这个默认构造函数在创建结构体对象时会被调用,用来初始化结构体的成员变量。 2. 显式构造函数:在C语言中,我们可以通过定义一个外部的函数来模拟结构体的构造函数。例如,在上面的例子中,我们可以定义一个函数来初始化Node结构体的成员变量,并返回一个已经初始化好的Node对象。例如,可以定义一个函数Node* createNode(int val, Node* next)来创建一个Node对象,并将val和next参数赋值给Node对象的成员变量。 总而言之,在C语言中,我们可以通过默认构造函数或者显式构造函数来初始化结构体的成员变量。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【C++】结构体构造函数和实例化详解-打包解决你的所有困惑(●‘◡‘●)](https://blog.csdn.net/icecreamTong/article/details/130627646)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [C++结构体作为函数参数传参的实例代码](https://download.csdn.net/download/weixin_38699302/14908236)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值