The writing method of C++ sort comparison function, the most comprehensive summary

When writing questions, I often encounter the need to write a sort comparison function by myself. If you don’t know how to write a comparison function, you will not be able to solve the problem even if you know the algorithm logic in it. Here are some custom comparison methods.

Preconditions

  1. Note that C++sort is in the algorithm package, pay attention to the include package
  2. The template of sort is below: Note that RandomAccessIterator can only be sorted ! ! What is RandomAccessIterator? If you need a detailed explanation, see: RandomAccessIterator cppreference , simply put, it is an iterator that can be accessed with any offset ! If this is not supported, sort cannot be used for sorting!

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. For example, the iterators in the map are Bidirectional iterators, which can only support iterator ++, - - does not support arbitrary offsets such as +n, so sort cannot be used for sorting !

  2. vector, deque support RandomAccessIterator, list, map, multimap, set and multiset only support bidirectional iterators!

usage

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

That is to say, there are two kinds, one is to use the non-writing comparison function, and the other is to customize the comparison function.
Note: No matter what kind of first two parameters are RandomAccessIterator, that is, variables cannot be directly passed in, and the corresponding iterator must be passed in. This is a very easy mistake for novices to make at the beginning.

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.

Type 1: Write the comparison function directly

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

Note: This comparison function must be written outside the class (global area) or declared as a static function! (I heard that it is because if it is a member function, it has a this pointer by default, which is different from the type of function object required by the sort function).

Type 2: Define a structure, construct a function object (function object), that is, overload the operator (), which is equivalent to constructing a function object

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

Type 3: Using lambada function

For simple function comparison, you can use the new feature lambada function of C++11 :

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

You can refer to: https://www.cnblogs.com/DswCnblog/p/5629165.html

Type 4: Use the default less and greater

In fact, both less and greater are function objects, that is, Function objects . What is a 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.

You can take a look at the less template:

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

It can be seen that less actually overloads a () operator. Note that less means that the first element is smaller than the second element , and it is actually sorted in ascending order .
Example:

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

Similarly, greater means descending order , this is his template and application example.
template:

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

Example:

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

Personally, I suggest using the first, second, and fourth methods, which are relatively intuitive. If there are other methods, you are welcome to discuss them.

Guess you like

Origin blog.csdn.net/Sansipi/article/details/127019948