【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

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值