1. sort()関数によるカスタムソート:
1.1、sort()テンプレートプロトタイプ:
1.1.1、デフォルトテンプレート:<
比較を使用して昇順で並べ替え
template <class_Randlt> // 模板参数为迭代器类型
void sort(_Randlt first, _RandIt last); // 参数为起止随机访问迭代器
前提は、aとb(_Randltイテレーターが指すオブジェクト)のサイズが同等でなければならないことです。比較素子のサイズがされ<
、発現する場合、行わa<b
値true
、その後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)
を使用して要素a
をb
比較し、サイズを比較します。これ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<b
値true
、その後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が比較関数をカスタマイズする場合、複数の基本的なコンテナーパラメーターベクトルが必要です。