目录
sort的自定义compare用法
之前想要降序排列的时候,总是首先sort,然后reverse,感觉很鸡肋,今天从力扣评论区发现,原来sort可以直接逆序
这里的comp是一个返回值为bool的函数,函数接收两个对象,然后返回bool(true or false),用来显示第一个对象是否可以放到第二个对象前面;请理解并记住理解这个函数的意义!!!
- 使用的排序方法是类似于快排的方法,时间复杂度为n*log2(n),执行效率较高;
- 传入的参数类型和需要排序的数据类型一致;
- functional提供了一堆基于模板的比较函数对象:equal_to、not_equal_to、greater、greater_equal、less、less_equal。对于这个问题来说,greater和less就足够了,直接拿过来用
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
bool myComp(int i,int j){
return i>j;
}
int main(){
//vector的排序
vector<int> array{1,2,6,7,33,-9,0};
sort(array.begin(),array.end());
sort(array.begin(),array.end(),myComp);
sort(array.begin(),array.end(),greater<int>());
return 0;
}
官方提供的四种comp比较函数
//c++库提供了这四种函数,可以直接使用
less<type>() //从小到大排序 <
grater<type>() //从大到小排序 >
less_equal<type>() // <=
gtater_equal<type>()// >=
priority_queue<int,vector<int>,less<int>> qless;//大顶堆 从大到小
priority_queue<int,vector<int>,greater<int>> qgreater;//小顶堆 从小到大
大顶堆:每个结点的值都大于或等于其左右孩子结点的值
小顶堆:每个结点的值都小于或等于其左右孩子结点的值
结构体的比较
对于结构体而言,不能直接使用sort,而应该重载运算符 < ,具体重载方法有三种:
1 重写比较函数comp
(先按照cnt从大从小排序,如果cnt相等,就按照val从小到大排序)
bool cmp(const number a,const number b)
{
if(a.cnt!=b.cnt)
return a.cnt > b.cnt;
return a.val < b.val;
}
2 结构体内重载运算符
struct number{
int val;
int cnt;
number():val(0),cnt(0){}
number(int r,int c):val(r),cnt(c){}
//结构体内部重载运算符
bool operator < (const number &a)
{
if(cnt != a.cnt)
return this->cnt > a.cnt;
return this->val < a.val;
}
};
3 结构体外重载运算符
bool operator < (const number &a,const number &b)
{
if(a.cnt != b.cnt)
return a.cnt > b.cnt;
return a.val < b.val;
}
测试
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
bool myComp(int i,int j){
return i>j;
}
bool myComp2 (const number a,const number b)
{
if(a.cnt != b.cnt)
return a.cnt > b.cnt;
return a.val < b.val;
}
struct number{
int val;
int cnt;
number():val(0),cnt(0){}
number(int r,int c):val(r),cnt(c){}
//结构体内部重载运算符
bool operator < (const number &a)
{
if(cnt != a.cnt)
return this->cnt > a.cnt;
return this->val < a.val;
}
};
bool operator < (const number &a,const number &b)
{
if(a.cnt != b.cnt)
return a.cnt > b.cnt;
return a.val < b.val;
}
int main(){
//自定义结构体的排序
number A[5];
A[0]={1,2};
A[1]={11,2};
A[2]={1,22};
A[3]={5,5};
A[4]={4,2};
sort(A,A+5);
return 0;
}
类的比较引发的两个问题
类的默认构造函数
默认的构造函数是无参的,而我们在实际的使用中,可能需要给我们在类里面定义的对象设置一个初始值,这样就需要写一个无参构造的构造函数,但是需要对我们定义的对象赋一个初值;
class MyCmp{
MyCmp(){};//编译器会自动添加的默认构造函数 ,无用
MyCmp():val(0),cnt(0){}; //无参构造函数
MyCmp(int v,int c):val(v),cnt(c){};//有参构造函数
};
类的构造函数、析构函数设置为private
这里主要涉及到了设计模式,在实际中,可能希望不让其他人直接定义一个类A的对象,而希望用户使用类A的子类。比如在子类里面将构造函数设置为public
class A
{ protected: A(){}
public: ....
};
calss B : public A
{ public: B(){}
....
};
A a; // error
B b; // ok