更具体的看【速记】C++ STL自定义排序 - 知乎 (zhihu.com)
sort
sort第三个位置放的greater<int>和less<int>萌新可能会弄错,这两个单词不是更大和更小的意思,而是大于和小于,并且比较就是自定义排序中的前者和后者。
如果是less,就代表 前者小于后者,那么自然是升序。
vector<int>a;a.push_back(3);a.push_back(2);sort(a.begin(),a.end(),less<int>());for(auto i:a)cout<<i<<" ";
同理的,greater的意思就是 前者大于后者 自然就是降序,代码就不再展示了。
默认写法,就是使用less和greater,但是有时候默认排序可能不满足我们的要求,就要自定义了,下面记录一下都可以的。
1、使用cmp函数,cmp里面的a,b含义就是容器的前者和后者,因此这么写也是升序。
bool cmp(int a,int b){return a<b;
}void solve(){vector<int>a;a.push_back(3);a.push_back(2);sort(a.begin(),a.end(),cmp);for(auto i:a)cout<<i<<" ";
}
当然你想容器里面套更多的元素也是可以的。
bool cmp(array<int,2> a,array<int,2> b){return a[0]>b[0];
}void solve(){vector<array<int,2>>a;a.push_back({1,2});a.push_back({2,3});sort(a.begin(),a.end(),cmp);for(auto i:a)cout<<i[0]<<" "<<i[1]<<endl;
}
2、写法Lambda函数,本质上还是在用函数,不过把函数写成Lambda形式了。
vector<int>a;a.push_back(3);a.push_back(2);auto cmp=[&](int a,int b){return a<b;};sort(a.begin(),a.end(),cmp);for(auto i:a)cout<<i<<" ";
或者使用Lambda形式的匿名表达式
vector<int>a;a.push_back(3);a.push_back(2);sort(a.begin(),a.end(),[](int a,int b){return a<b;});for(auto i:a)cout<<i<<" ";
tip:改成int &a,int &b,不会更快,因为sort函数不会产生新数组,是在原有的数组上排序,观察sort可以发现,第一个是 首地址,第二个是 结束地址。
当然也可以使用function来封装函数。
vector<int>a;a.push_back(3);a.push_back(2);function<bool(int a,int b)>cmp=[&](int a,int b){return a<b;};sort(a.begin(),a.end(),cmp);for(auto i:a)cout<<i<<" ";
3、重载运算符(个人感觉写个cmp函数更方便)
struct Node{int val;bool operator < (const Node &b){return val>b.val;}
}a[3];void solve(){a[1].val=2;a[2].val=3;sort(a+1,a+2+1);cout<<a[1].val<<" "<<a[2].val;
}
因为默认是 less 排序,即升序,所以我们要重载小于号。
比如这里改成 前者大于后者(这里val就是前者,右边的那个常量就是后者)
输出就是
会自动排序的容器
类似set,map这种容器,我们就不能用sort了,要提前定好一个排序类,重载内部的排序。
比较方式不变,依旧是前者和后者的比较。
tip:优先队列排序,输出最后面的(如less升序,就输出最大值。greater降序,就输出最小值),如果要 重载优先队列,这一点要多注意。
理论上map和set只有 key是自动排序的,value不会,所以不建议对value自定义排序。
比如下面要对map重载成自动降序。
struct MyMap{bool operator() (const int &a,const int &b)const{return a>b;}
};map<int,int,MyMap>f;void solve(){f[1]=2;f[2]=1;for(auto i:f)cout<<i.fr<<" ";
}
显然这是没必要的。
因为map可以逆序遍历。
正序是 begin()->end()
逆序就是 rbegin()->rend()
r就是单词reverse(反向、逆向都行)的缩写。
重载自动排序的类,里面格式都是固定的,比如 bool operator() (const &,consg &)const{}
下面再放一个对自定义类自动排序的。
struct Node{int a,b;
};struct MyMap{bool operator() (const Node &A,const Node &B)const{return A.a<B.a;}
};map<Node,bool,MyMap>f;void solve(){f[{2,1}]=1;f[{1,2}]=1;for(auto i:f){cout<<i.fr.a<<" "<<i.fr.b<<endl;}
}