C++自定义比较:比较函数、仿函数、重载操作符
sort函数
sort函数包含在头文件为#include< algorithm>的c++标准库中,默认升序。
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
优先级队列
优先级队列的a < b说明a的优先级不如b,优先队列里面是默认使用大根堆,也就是更大的数更优先。
priority, greater< a> >,a要完全一样。
比较函数的自定义方法
①静态compare函数
sort:
static bool compare(string& s1, string& s2){
return s1+s2 < s2+s1;
}
sort(vs.begin(), vs.end(), compare);
优先级队列:注意用decltype(&cmp) q(cmp)
static bool cmp(pair<int, int>& m, pair<int, int>& n) {
return m.second > n.second;
}
priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(&cmp)> q(cmp);
②传入函数对象(仿函数)
函数对象是行为类似函数的对象。一个类对象,表现出一个函数的特征,即通过对象名+(参数列表)的方式使用一个类对象。
sort:有()
s1 = "2", s2 = "3", s1 + s2 = "23" < "32", s1放在s2前面才返回true,sort按照组合起来数字更小的顺序排序
struct compare{
bool operator ()(string& s1, string& s2){
return s1+s2 < s2+s1;
}
};
sort(vs.begin(), vs.end(), compare()); / 注意有()
优先级队列:无()
如果a.second < b.second,返回true,即a < b,即b更优先,此处是second更大的更优先
另一种思路,对于sort此处是second更小的排在前面,优先级队列相反,所以是second更大的排在前面。
struct compare{
bool operator ()(pair<int, int>& a, pair<int, int>& b){
return a.second < b.second;
}
};
priority_queue<pair<int, int>, vector<pair<int, int>>, compare> pq;
如果a->val < b->val,返回false,即a > b,即a更优先,此处是val更小的更优先。
另一种思路,对于sort此处是val更大的排在前面,优先级队列相反,所以val更小的排在前面。
struct compare{
bool operator ()(ListNode* a, ListNode* b){
return a->val > b->val;
}
};
③重载 <
这种方式使得复杂结构变得像基本数据类型一样可比较了。这样就不用传比较器了,因为默认的比较器这时已经生效了。对于 cpp 代码,重载运算符不管对于 struct 还是 class 都是很方便的,都是在自己定义的结构体或类类型里加一个重载的函数即可。
④lambda表达式法
sort:a > b才返回true,才能按照a-b的顺序排列,所以此处为降序
sort(vs.begin(), vs.end(), [](int a, int b){return a > b;});
相同元素排序前后相对位置不变。
不要用greater排序pair,用自定义cmp函数,或者仿函数。
stable_sort的自定义比较函数一定要写const。 也建议sort写自定义函数的时候都加上const。
sort和优先级队列对元素的呈现形式是相反的
对于priority_queue,更优先的元素在前端,默认情况下与less<>()相同,更大的数更优先。
但如果第三个参数为greater<>() 或者重载了()、或者重载了 < 、更小的的数更优先。
方法1:
// 按pair的第二个元素降序排列
static bool cmp(pair<int,int> a, pair<int, int> b){
return a.second > b.second;
}
priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(&cmp)> q(cmp);
方法2:
struct cmp1{
bool operator()(pair<int,int> a, pair<int, int> b){
return a.second > b.second;
}
};
priority_queue<pair<int,int> , vector<pair<int,int>>, cmp1> q;
priority_queue<int> q;//默认是从大到小
priority_queue<int, vector<int> ,less<int> >q;//从大到小排序
priority_queue<int, vector<int>, greater<int> >q;//从小到大排序
#include
#include
#include
#include
using namespace std;
int main() {
int a[] = { 3, 5, 6, 2, 1, 4 };
sort(a, a + 6);
cout << "sort默认:";
for (auto e : a)
cout << e << " ";
cout << endl;
sort(a, a + 6, greater<int>());
cout << "sort_greater:";
for (auto e : a)
cout << e << " ";
cout << endl;
sort(a, a + 6, less<int>());
cout << "sort_less:";
for (auto e : a)
cout << e << " ";
cout << endl;
priority_queue<int> mypriqueue;
int b[] = { 3, 5, 6, 2, 1, 4 };
for (auto e : b) {
mypriqueue.push(e);
}
cout << "优先级队列默认:";
while (!mypriqueue.empty()) {
cout << mypriqueue.top() << " ";
mypriqueue.pop();
}
cout << endl;
priority_queue<int, vector<int>, greater<int>> q1;
for (auto e : b)
q1.push(e);
cout << "优先级队列_greater:";
while (!q1.empty()) {
cout <<q1.top() << " ";
q1.pop();
}
cout << endl;
priority_queue<int, vector<int>, less<int>> q2;
for (auto e : b)
q2.push(e);
cout << "优先级队列_less:";
while (!q2.empty()) {
cout << q2.top() << " ";
q2.pop();
}
return 0;
}
输出:
sort默认:1 2 3 4 5 6
sort_greater:6 5 4 3 2 1
sort_less:1 2 3 4 5 6
优先级队列默认:6 5 4 3 2 1
优先级队列_greater:1 2 3 4 5 6
优先级队列_less:6 5 4 3 2 1
包含在< alogotithm > 中
reverse函数用于反转在[first,last)范围内的顺序(包括first指向的元素,不包括last指向的元素),reverse函数没有返回值
advance(it, n)
it 表示某个迭代器,n 为整数。该函数的功能是将 it 迭代器前进或后退 n 个位置。
n为正数,则前进(右移);n为负数,则后退(左移)。
advance() 函数本身不会检测 it 迭代器移动 n 个位置的可行性,如果 it 迭代器的移动位置超出了合理范围,it 迭代器的指向将无法保证,此时使用 *it 将会导致程序崩溃。