【c++】 自定义排序和比较函数(适用于set,sort等需要排序/去重的地方)

当对自定义类(如下面的代码)进行排序或者将自定义类放入set结构时,就需要自定义比较函数,否则会报错。对基本数据类型排序或者放入set时不需要此函数,因为是STL中自定义了比较函数,会默认调用,无需自定义。

#include<iostream>
#include<set>
using namespace std;
class A{
public:
  int a,b,c;
  A(){};
  A(int aa,int bb,int cc){
    a = aa;
    b = bb;
    c = cc;
  }
};

如何定义比较函数?

方法一:类外定义比较函数(适用于sort)

bool compareS (const A &th,const A &other) {
  if((th.a == other.a) && (th.b == other.b) && (th.c == other.c))
    return false;
  else {
    if( th.a != other.a)
      return th.a < other.a;
    else if(th.b != other.b)
      return th.b < other.b;
    else
      return th.c < other.c;
  }
}

int main(){
  A aa(1,2,3);
  A bb(1,3,3);
  vector<A> SA;
  SA.push_back(aa);
  SA.push_back(bb);
  sort(SA.begin(),SA.end(),compareS);

}

方法二:类内重载 < 操作符

class A{
public:
  int a,b,c;
  A(){};
  A(int aa,int bb,int cc){
    a = aa;
    b = bb;
    c = cc;
  }
  bool operator< (const A &other) const{
    if((a == other.a) && (b == other.b) && (c == other.c)){
        return false;
    }
    else {
      if( a != other.a)
        return a < other.a;
      else if(b != other.b)
        return b < other.b;
      else 
        return c < other.c;
    }
  }
};

int main(){
  A aa(1,2,3);
  A bb(1,3,3);
  vector<A> SA;
  SA.push_back(aa);
  SA.push_back(bb);
  sort(SA.begin(),SA.end());
  set<A> ff;
  ff.insert(aa);
  ff.insert(bb);
  cout<<ff.size()<<endl;
}

方法三:类外定义函数对象(仿函数)/重载()

struct compare{
  bool operator() (const A &th,const A &other) {
    if((th.a == other.a) && (th.b == other.b) && (th.c == other.c))
      return false;
    else {
      if( th.a != other.a)
        return th.a < other.a;
      else if(th.b != other.b)
        return th.b < other.b;
      else
        return th.c < other.c;
    }
  }
};

int main(){
  A aa(1,2,3);
  A bb(1,3,3);
  vector<A> SA;
  SA.push_back(aa);
  SA.push_back(bb);
  sort(SA.begin(),SA.end(),compare());
  set<A,compare> ff;
  ff.insert(aa);
  ff.insert(bb);
  cout<<ff.size()<<endl;
}

set容器在判定已有元素a和新插入元素b是否相等时,是这么做的:
1)将a作为左操作数,b作为有操作数,调用比较函数,并返回比较值
2)将b作为左操作数,a作为有操作数,再调用一次比较函数,并返回比较值。

如果1、2两步的返回值都是false,则认为a、b是相等的,则b不会被插入set容器中

如果1、2两步的返回值都是true,则可能发生未知行为

因此,在比较时,当两个对象相等时一定要返回 false。

  bool operator() (const A &th,const A &other) {
    if((th.a == other.a) && (th.b == other.b) && (th.c == other.c))
      return false;

同时,在自定义对象的set中不需要重载 == 操作符,<操作符已经可以完成判断相等的功能。

参考:https://blog.csdn.net/lishuhuakai/article/details/51404214

https://blog.csdn.net/wzzfeitian/article/details/70171512


另有高性能,深度学习,人工智能培训,报名咨询优惠等着你!

http://www.huodongxing.com/event/6509102612000?qd=xielulu

发布了46 篇原创文章 · 获赞 14 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/xll_bit/article/details/101302124