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
前面。
int myints[] = {32,71,12,45,26,80,53,33};
std::vector<int> myvector (myints, myints+8);
std::sort (myvector.begin(), myvector.begin()+4);
- a,b为class/struct对象:类中或类外必须重载<比较函数
class A
{
public:
int v1;
int v2;
A(int n) : v1(n), v2(0) {}
bool operator < (const A & a1) const
{
return v1 < a1.v1;
}
};
bool operator < (const A & a1, const A & a2)
{
return a1.v1 < a2.v1;
}
A a2[5] = { 13, 12, 9, 8, 16 };
std::sort (a2, a2+5);
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量
bool GreaterA(const A & a1, const A & a2)
{
return a1.v1 > a2.v1;
}
std::sort (a2, a2+5, GreaterA);
Pred op
为函数对象:类成员函数返回值必须为bool量
struct LessA
{
bool operator() (const A & a1, const A & a2)
{
return (a1.v1) < (a2.v1);
}
}LessA_1;
std::sort (a2, a2+5, LessA_1);
std::sort (a2, a2+5, LessA());
以上两行结果是一样的,下面一行是先调用了LessA类构造函数构造处函数对象后作为参数使用
STL中定义了一些函数对象类模板,都位于头文件 functional 中。例如,greater 模板的源代码如下:
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、函数对象详细介绍:
如果一个类将()运算符重载为成员函数,这个类就称为函数对象类,这个类的对象就是函数对象。函数对象是一个对象,但是使用的形式看起来像函数调用,实际上也执行了函数调用,因而得名。
推荐学习:C++函数对象及在sort()函数中应用详解
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>
> class set;
2.1.1、默认排序方式:利用<
比较,升序排列
int myints[] = { 4,2,7,1,9 };
set<int> mySet(myints, myints + 5);
前提是a、b必须可比较大小。元素比较大小是用<
进行的,如果表达式a<b
的值为 true
,则 a
排在 b
前面。
2.1.2、自定义比较函数:
自定义比较函数,可以当参数为结构体时,指定比较的成员变量。
Compare
为函数指针:函数返回值必须为bool量 复杂不推荐
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);
Compare
为函数对象类型:类成员函数返回值必须为bool量 简单,推荐
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);
2.2、map容器原型:默认也是升序
map使用键进行排序,与set类似,均常用函数对象类型作比较。
在map基础上无法实现按值排序,只能将其转换到其他容器进行。
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;
std::map<int, int, std::greater<int>> mi;
2.2.2、map实现按值排序:
将map的键值对放入vector中,利用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。
Container:存储元素的内部基础容器对象的类型,其value_type应为T,别名为成员类型priority_queue :: container_type。
2.3.1、默认排序方式:升序
int myints[] = { 10,60,50,20 };
std::priority_queue<int> second(myints, myints + 4);
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);
std::priority_queue<int, std::vector<int>, mycomparison>
由于模板参数必须顺序赋值,不能调过中间的基本容器参数,所以需要有std::vector<int>,
部分。
总结:
1、所有容器、sort()函数默认都是升序排列。
2、可以使用函数指针与函数对象方法进行自定义排序。
3、priority_queue自定义比较函数时需要多家一个基本容器参数vector。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)