STLカスタムソート関数:sort()関数、priority_queue、set、mapおよびその他のコンテナーソート関数

1. sort()関数によるカスタムソート:

1.1、sort()テンプレートプロトタイプ:
1.1.1、デフォルトテンプレート:<比較を使用して昇順で並べ替え

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

前提は、aとb(_Randltイテレーターが指すオブジェクト)のサイズが同等でなければならないことです。比較素子のサイズがされ<、発現する場合、行わa<btrue、その後aに行bフロント。

  • a、bは値オブジェクトです:サイズを直接比較できます
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はクラス/構造体オブジェクトです。比較関数はクラス内またはクラス外でオーバーロードする必要があります
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、カスタムソートテンプレート:

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

op(a, b)使用要素ab比較し、サイズ比較しますこれPred opは、関数ポインターまたは関数オブジェクトにすることができます。式の値がtrueの場合、aはbよりも小さくなります。

  • Pred op関数ポインターの場合:関数の戻り値はブール値でなければなりません
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 op関数オブジェクトとして:クラスメンバー関数の戻り値はブール値でなければなりません
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类构造函数构造处函数对象后作为参数使用

一部の関数オブジェクトクラステンプレートSTL 定義されており、すべてテンプレートファイルのヘッダーファイルにあります。たとえば、大きいテンプレートのソースコードは次のとおりです。

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。関数オブジェクトの詳細な紹介:
クラスが()演算子をメンバー関数としてオーバーロードする場合、このクラスは関数オブジェクトクラスと呼ばれ、このクラスのオブジェクトは関数オブジェクトです。関数オブジェクトはオブジェクトですが、関数呼び出しのように見えますが、実際には関数呼び出しを実行するため、名前が付けられます。
推奨される学習:sort()関数でのC ++関数オブジェクトとそのアプリケーション

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コンテナのカスタムソート関数:
2.1、setコンテナプロトタイプ:

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

2.1.1。デフォルトのソート方法:<比較を使用して昇順で並べ替え

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

aとbのサイズは同等でなければならないという前提があります。比較素子のサイズがされ<、発現する場合、行わa<btrue、その後aに行bフロント。
2.1.2。カスタマイズされた比較関数:
パラメーターが構造体である場合、カスタマイズされた比較関数は比較用のメンバー変数を指定できます。

  • Compare関数ポインターの場合:関数の戻り値はブール値でなければなりません 推奨されない複合施設
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 升序排序
  • Compare関数オブジェクトタイプ:クラスメンバー関数の戻り値はブール値である必要があります シンプル、推奨
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。マップコンテナプロトタイプ:デフォルトも昇順です
マップはソートにキーを使用しますセットと同様に、それらは一般的に関数オブジェクトタイプと比較されます。
値による並べ替えは、マップに基づいて行うことはできず、他のコンテナに変換することしかできません。

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。マップは値によるソートを実装します:マップ
のキーと値のペアをベクターに入れ、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コンテナのプロトタイプ:

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

T:要素のタイプ。エイリアスは、メンバータイプpriority_queue :: value_typeです。
コンテナー:要素を格納する内部基本コンテナーオブジェクトのタイプ。そのvalue_typeはTである必要があり、エイリアスはメンバータイプpriority_queue :: container_typeです。
2.3.1、デフォルトのソート方法:昇順

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

2.3.2。カスタム比較関数:

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

テンプレートパラメータは順番に割り当てる必要があるため、中央の基本的なコンテナパラメータは調整できないため、いくつか必要ですstd::vector<int>,

総括する:

1.デフォルトでは、すべてのコンテナーおよびsort()関数は昇順で配置されます。
2.カスタムソートには、関数ポインターと関数オブジェクトメソッドを使用できます。
3. priority_queueが比較関数をカスタマイズする場合、複数の基本的なコンテナーパラメーターベクトルが必要です。

おすすめ

転載: blog.csdn.net/qq_33726635/article/details/106690587