STL custom sorting functions: sort() function; priority_queue, set, map and other container sorting functions

1. Custom sort by sort() function:

1.1, sort() template prototype:
1.1.1, default template:Use <comparison, sort ascending

template <class_Randlt> // 模板参数为迭代器类型
void sort(_Randlt first, _RandIt last); // 参数为起止随机访问迭代器

The premise is that a and b (the object pointed to by the _Randlt iterator) must be comparable in size. Compare the size of the element is <carried out, if the expression a<bvalue true, then the arow at bthe front.

  • a, b are value objects: the size can be directly compared
int myints[] = {
    
    32,71,12,45,26,80,53,33};
std::vector<int> myvector (myints, myints+8);               // 32 71 12 45 26 80 53 33
// 默认sort模板,使用<排序
std::sort (myvector.begin(), myvector.begin()+4);           //(12 32 45 71)26 80 53 33
  • a, b are class/struct objects: the comparison function must be overloaded in or outside the class
class A
{
    
    
public:
    int v1;
    int v2;
    A(int n) : v1(n), v2(0) {
    
    }
    // 方式1:
    bool operator < (const A & a1) const
	{
    
      //重载为 A 的 const 成员函数,重载为非 const 成员函数在某些编译器上会出错
	   return v1 < a1.v1;
	}
};
// 方式2:
bool operator < (const A & a1, const A & a2) 
{
    
      // 类外重载,调用<比较函数时会先在本文件内查找匹配的函数,没有才调用全局空间的<函数
    return a1.v1 < a2.v1;
}

// 默认sort模板,但元素自定义了比较函数
A a2[5] = {
    
     13, 12, 9, 8, 16 };
std::sort (a2, a2+5);           // 8, 9, 12, 13, 16

1.1.2, custom sorting template:

template <class_Randlt, class Pred>
void sort(_Randlt first, _RandIt last, Pred op); // 多了一个比较函数指针或对象

Use expressions op(a, b)to compare elements aand bcompare sizes,Which Pred opcan be a function pointer or a function object, if the value of the expression is true, then a is smaller than b.

  • Pred opFor function pointer: the return value of the function must be bool
bool GreaterA(const A & a1, const A & a2)
{
    
      //v值大的元素作为较小的数
    return a1.v1 > a2.v1;
}
std::sort (a2, a2+5, GreaterA);           // 16, 13, 12, 9, 8  按v1的值从大到小排序
  • Pred opAs a function object: the return value of a class member function must be a bool amount
struct LessA  // 自定义排序对象,struct换成class也可以
{
    
    
    bool operator() (const A & a1, const A & a2)
    {
    
      //v的个位数小的元素就作为较小的数
        return (a1.v1) < (a2.v1);
    }
}LessA_1; // LessA为对象类型,LessA_1为对象
std::sort (a2, a2+5, LessA_1);           // 8, 9, 12, 13, 16  按v1的值从小到大排序
std::sort (a2, a2+5, LessA());           // 8, 9, 12, 13, 16  按v1的值从小到大排序
以上两行结果是一样的,下面一行是先调用了LessA类构造函数构造处函数对象后作为参数使用

Some function object class templates are defined in STL , all of which are located in the header file functional. For example, the source code of the greater template is as follows:

template <class T>
struct greater
{
    
    
    bool operator()(const T& x, const T& y) const{
    
    
        return x > y;
    }
};
int a[4] = {
    
    3, 5, 34, 8};
sort( a, a+4, greater<int>() );

1.2. Detailed introduction of function objects:
If a class overloads the () operator as a member function, this class is called a function object class, and the object of this class is a function object. A function object is an object, but it looks like a function call, but it actually executes the function call, hence the name.
Recommended learning: C++ function object and its application in the sort() function

class CAverage // 函数对象类
{
    
    
public:
    double operator()(int a1, int a2, int a3)
    {
    
      //重载()运算符
        return (double)(a1 + a2 + a3) / 3;
    }
};

CAverage average // 函数对象
cout << average(3, 2, 3); // 像函数一样调用函数对象

2. Set, map, priority_queue container custom sorting functions:
2.1, set container prototype:

template < class T,                        // 键/值类型
           class Compare = less<T>,        // 比较函数/对象
           class Alloc = allocator<T>      // set::allocator_type
           > class set;

2.1.1. The default sorting method:Use <comparison, sort ascending

int myints[] = {
    
     4,2,7,1,9 };
set<int> mySet(myints, myints + 5);    // 1, 2, 4, 7, 9 默认升序排序

The premise is that a and b must be comparable in size. Compare the size of the element is <carried out, if the expression a<bvalue true, then the arow at bthe front.
2.1.2. Customized comparison function:
Customized comparison function can specify the member variable for comparison when the parameter is a structure.

  • CompareFor function pointer: the return value of the function must be bool Complex not recommended
bool fncomp(int lhs, int rhs) {
    
     return lhs<rhs; } // 比较函数
int myints[] = {
    
     4,2,7,1,9 };
set<int, bool(*)(int, int)> mySet(fncomp);  // 变量声明方式,较复杂
sixth.insert(4);
sixth.insert(2);
sixth.insert(7);
sixth.insert(1);
sixth.insert(9); // 1, 2, 4, 7, 9 升序排序
  • CompareFunction object type: the return value of the class member function must be bool Simple, recommended
struct classcomp {
    
     // 比较函数对象
	bool operator() (const int& lhs, const int& rhs) const
	{
    
    
		return lhs<rhs;
	}
};
int myints[] = {
    
     4,2,7,1,9 };
set<int, classcomp> mySet(myints, myints + 5);    // 1, 2, 4, 7, 9 默认升序排序

2.2. Map container prototype: The default is also ascending order.
Map uses keys for sorting. Similar to set, they are commonly compared with function object types.
Sorting by value cannot be achieved on the basis of map, and it can only be converted to other containers.

struct classcomp {
    
    
	bool operator() (const char& lhs, const char& rhs) const
	{
    
    
		return lhs<rhs;
	}
};
std::map<char, int, classcomp> first;
first['a'] = 60;
first['c'] = 30;
first['b'] = 50;
first['d'] = 70; // a, b, c, d 根据键排序
std::map<int, int, std::greater<int>> mi; // 利用函数对象类模板实现降序排序

2.2.2. Map implements sorting by value:
Put the key-value pairs of the map into the vector, and use sort to customize the sort.

bool cmp(const pair<string,int> &p1, const pair<string,int> &p2) {
    
    
    return p1.second > p2.second; // 按值排序
}

vector<pair<string,int> > vpr;
for(map<string,int>::iterator it = mp.begin(); it != mp.end(); it++){
    
    
    vpr.push_back(make_pair(it->first,it->second);
}
sort(vpr.begin(),vpr.end(),cmp);

2.3. Priority_queue container prototype:

template <class T, class Container = vector<T>,
  class Compare = less<typename Container::value_type> > class priority_queue;

T: The type of element. The alias is the member type priority_queue :: value_type.
Container: The type of the internal basic container object storing the element, its value_type should be T, and the alias is the member type priority_queue :: container_type.
2.3.1, the default sorting method: ascending

int myints[] = {
    
     10,60,50,20 };
std::priority_queue<int> second(myints, myints + 4); // 10, 20, 50, 60

2.3.2. Custom comparison function:

class mycomparison
{
    
    
public:
	bool operator() (const int& lhs, const int&rhs) const
	{
    
    
		return (lhs<rhs);
	}
};
std::priority_queue<int, std::vector<int>, std::greater<int> > 
	third(myints, myints + 4); // 60, 50, 20, 10
std::priority_queue<int, std::vector<int>, mycomparison> // 10, 20, 50, 60

Because the template parameters must be assigned in order, the basic container parameters in the middle cannot be adjusted, so some are required std::vector<int>,.

to sum up:

1. All containers and sort() functions are arranged in ascending order by default.
2. You can use function pointers and function object methods for custom sorting.
3. When priority_queue customizes the comparison function, more than one basic container parameter vector is required.

Guess you like

Origin blog.csdn.net/qq_33726635/article/details/106690587