比较器解决排序问题
比较器–C++/Java实现
对于任意比较器,对 返回值 都有统一的规范:
返回值
<
0
:
<0:
<0:
o
1
o1
o1 排在
o
2
o2
o2 前面
返回值
>
0
:
>0:
>0:
o
2
o2
o2 排在
o
1
o1
o1 前面
返回值
=
0
:
=0:
=0: 谁排前面都可以
实例1
C++:
//降序
bool compare(int a,int b){
return a>b;
}
sort(arr.begin(),arr.end(),compare);
C++ Lambda表达式
std::sort(ans.begin(),ans.end(),[&](vector<int>& v1,vector<int>& v2){
return (std::abs(v1[0]-rCenter)+std::abs(v1[1]-cCenter))<
(std::abs(v2[0]-rCenter)+std::abs(v2[1]-cCenter));
});
Java:
A r r a y s . s o r t ( ) Arrays.sort ( ) Arrays.sort() 默认升序,定义比较器而不用重新写就可以实现降序
import java.util.Arrays;
public class Comparator {
public static void main(String[] args) {
int[] arr= {1,0,9,6,2,5,6,7,2,5};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
}
import java.util.Arrays;
import java.util.Comparator;
public class MyComparator {
public static class Compare implements Comparator<Integer>{
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
}
public static void main(String[] args) {
Integer[] arr= {1,0,9,6,2,5,6,7,2,5};
Arrays.sort(arr,new Compare());
System.out.println(Arrays.toString(arr));
}
}
实例2
定义学生类,按照 I D ID ID 升序
C++:
#include<iostream>
#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;
class Student{
public:
Student(string myName,int myId,int myAge):name(myName),id(myId),age(myAge){}
void outPut(){
cout<<name<<" "<<id<<" "<<age<<endl;
}
string getName(){
return name;
}
int getId(){
return id;
}
int getAge(){
return age;
}
private:
string name;
int id;
int age;
};
//比较器
bool compare(Student s1,Student s2){
return s1.getId()<s2.getId();
}
void print(const vector<Student>& arr){
for(auto k:arr){
k.outPut();
}
}
int main(){
vector<Student>arr;
// Student tmp;
int len=5;
for(int i=0;i<len;++i){
string name;
int id;
int age;
cin>>name>>id>>age;
Student stu(name,id,age);
arr.push_back(stu);
}
sort(arr.begin(),arr.end(),compare);
print(arr);
}
/*John 2001 23
Mary 2008 21
Hun 2003 29
Wu 2002 24
Ma 2005 22
======================
John 2001 23
Wu 2002 24
Hun 2003 29
Ma 2005 22
Mary 2008 21*/
Java:
import java.util.Arrays;
import java.util.Comparator;
public class MyComparator {
public static class Student{
public String name;
public int ID;
public int age;
Student(String name,int ID,int age){
this.name=name;
this.ID=ID;
this.age=age;
}
}
public static class Compare implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
return o1.ID-o2.ID;
}
}
public static void main(String[] args) {
Student[] stus=new Student[5];
stus[0]=new Student("John", 2001, 23);
stus[1]=new Student("Mary", 2008, 21);
stus[2]=new Student("Hun", 2003, 29);
stus[3]=new Student("Wu", 2002, 24);
stus[4]=new Student("Ma", 2005, 22);
Arrays.sort(stus,new Compare());
for(int i=0;i<stus.length;++i) {
System.out.println(stus[i].name+" "+stus[i].ID+" "+stus[i].age);
}
}
}
实例3
按照班级升序,按照年龄降序
C++:
//按照班级升序,按照年龄降序
#include<iostream>
#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;
class Student{
public:
Student(string myName,int myId,int myClass,int myAge):name(myName),id(myId),Class(myClass),age(myAge){}
void outPut(){
cout<<name<<" "<<id<<" "<<Class <<" "<<age<<endl;
}
string getName(){
return name;
}
int getId(){
return id;
}
int getClass(){
return Class;
}
int getAge(){
return age;
}
private:
string name;
int id;
int Class;
int age;
};
//比较器
bool compare(Student s1,Student s2){
if(s1.getClass()!=s2.getClass()){
return s1.getClass()<s2.getClass();
}
return s1.getAge()>s2.getAge();
}
void print(const vector<Student>& arr){
for(auto k:arr){
k.outPut();
}
}
int main(){
vector<Student>arr;
// Student tmp;
int len=5;
for(int i=0;i<len;++i){
string name;
int id;
int Class;
int age;
cin>>name>>id>>Class>>age;
Student stu(name,id,Class,age);
arr.push_back(stu);
}
sort(arr.begin(),arr.end(),compare);
print(arr);
}
John 2008 1901 23
Wu 2002 1904 24
Hun 2003 1906 29
Ma 2005 1908 22
Mary 2001 1901 21
======================
John 2008 1901 23
Mary 2001 1901 21
Wu 2002 1904 24
Hun 2003 1906 29
Ma 2005 1908 22
*/
Java:
import java.util.Arrays;
import java.util.Comparator;
public class MyComparator {
public static class Student{
public String name;
public int ID;
public int age;
public int classNo;
Student(String name,int ID,int age,int classNo){
this.name=name;
this.ID=ID;
this.age=age;
this.classNo=classNo;
}
}
public static class Compare implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
if(o1.classNo!=o2.classNo) {
return o1.classNo-o2.classNo;
}
return o2.age-o1.age;
}
}
public static void main(String[] args) {
Student[] stus=new Student[7];
stus[0]=new Student("Mary", 2007, 25,1908);
stus[1]=new Student("John", 2008, 23,1901);
stus[2]=new Student("Wu", 2002, 24,1904);
stus[3]=new Student("Mar", 2011, 19,1908);
stus[4]=new Student("Hun", 2003, 29,1906);
stus[5]=new Student("Ma", 2005, 22,1908);
stus[6]=new Student("Mary", 2001, 21,1901);
Arrays.sort(stus,new Compare());
for(int i=0;i<stus.length;++i) {
System.out.println(stus[i].name+" "+stus[i].classNo+" "+stus[i].age+" "+stus[i].ID);
}
}
}
实例4
自定义类型的堆,堆的组织结构是基于比较的,必须提供自定义类型的比较规则,这就可以用到比
较器。
按照年龄组织成小根堆
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
public class MyComparator {
public static class Student{
public String name;
public int ID;
public int age;
public int classNo;
Student(String name,int ID,int age,int classNo){
this.name=name;
this.ID=ID;
this.age=age;
this.classNo=classNo;
}
}
public static class Compare implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
return o1.age-o2.age;
}
}
public static void main(String[] args) {
Student[] stus=new Student[7];
stus[0]=new Student("Mary", 2007, 25,1908);
stus[1]=new Student("John", 2008, 23,1901);
stus[2]=new Student("Wu", 2002, 24,1904);
stus[3]=new Student("Mar", 2011, 19,1908);
stus[4]=new Student("Hun", 2003, 29,1906);
stus[5]=new Student("Ma", 2005, 22,1908);
stus[6]=new Student("Mary", 2001, 21,1901);
PriorityQueue<Student> heap=new PriorityQueue<Student>(new Compare());
heap.add(stus[0]);
heap.add(stus[1]);
heap.add(stus[2]);
heap.add(stus[3]);
heap.add(stus[4]);
heap.add(stus[5]);
heap.add(stus[6]);
while(!heap.isEmpty()) {
Student s=heap.poll();
System.out.println(s.name+" "+s.age+" "+s.classNo+" "+s.ID);
}
}
}
题目1
#include <iostream>
#include<stdio.h>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
class GDP{
public:
string city;
double first;
double second;
double third;
double ratio;
double sum;
GDP(string s,double a,double b,double c){
city=s;
first=a;
second=b;
third=c;
ratio=c/(a+b+c);
sum=a+b+c;
}
};
//比较器
bool compare(GDP s1,GDP s2){
return s1.sum>s2.sum;
}
bool compare1(GDP s1,GDP s2){
return s1.ratio>s2.ratio;
}
int main() {
int N;
cin>>N;
vector<GDP>vec;
for(int i=0;i<N;++i){
string s;double a,b,c;
cin>>s>>a>>b>>c;
GDP gdp(s,a,b,c);
vec.push_back(gdp);
}
sort(vec.begin(),vec.end(),compare);
cout<<vec[0].city<<" ";
sort(vec.begin(),vec.begin()+3,compare1);
cout<<vec[0].city<<" ";
}
Lambda表达式定义比较器
class Solution {
public:
vector<vector<int>> allCellsDistOrder(int rows, int cols, int rCenter, int cCenter) {
vector<vector<int>>ans;
for(int i=0;i<rows;++i){
for(int j=0;j<cols;++j){
vector<int>v;
v.push_back(i);
v.push_back(j);
ans.push_back(v);
}
}
std::sort(ans.begin(),ans.end(),[&](vector<int>& v1,vector<int>& v2){
return (std::abs(v1[0]-rCenter)+std::abs(v1[1]-cCenter))<
(std::abs(v2[0]-rCenter)+std::abs(v2[1]-cCenter));
});
return ans;
}
};
重新排列日志文件
class Solution {
public:
static bool compare(string s1,string s2){
int i=0;
while(s1[i]!=' '){
i++;
}
int j=0;
while(s2[j]!=' '){
j++;
}
string tmp1=s1.substr(i+1,s1.length());
string tmp2=s2.substr(j+1,s2.length());
if(tmp1==tmp2){
return s1.substr(0,i)<s2.substr(0,j);
}else{
return tmp1<tmp2;
}
}
vector<string> reorderLogFiles(vector<string>& logs) {
vector<string>letter;
vector<string>number;
for(string s:logs){
if(s[s.length()-1]>='0'&&s[s.length()-1]<='9'){
number.push_back(s);
}else{
letter.push_back(s);
}
}
sort(letter.begin(),letter.end(),compare);
for(string s:number){
letter.push_back(s);
}
return letter;
}
};