C++ STL set详解

本文详细介绍了C++标准库中的关联容器std::set,它是一个用于存储唯一对象的排序集合。set内部由红黑树实现,提供了高效的插入、删除和查找操作。文章通过实例展示了如何在set中存储整数和自定义类型,并解释了如何自定义比较函数以满足排序需求。同时,文章还讨论了set中元素相等性的判断方法。
摘要由CSDN通过智能技术生成

template<
    class Key,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<Key>
> class set;

std::set是一种关联型容器,是一个排序集合,可以用来存放Key类型的对象。set集合里的对象都是唯一的,所以通常可以用set来做去重。其中排序是通过Compare这个对比函数对象来完成的,因为要排序,对于自定义类型需要告诉编译器这个类型比大小的规则。

要使用std::set需要指定一个对比函数(Compare),这个对比函数用来对比哪个元素更小,它的唯一性也是通过这个对比函数来确保的。因为标准库底层是用红黑树来实现,它的搜索,删除和插入操作具有对数复杂度。下面来看一个例子

#include <algorithm>
#include <iostream>
#include <set>
 
int main() {
  std::set<int> set = { 3, 1, 4, 1, 5, 9, 2, 6, 5 };
  std::for_each(set.cbegin(), set.cend(), [](int x) {
    std::cout << x << ' ';
  });
  std::cout << '\n';
}

这个例子中由于set存放的类型是int类型,所以不需要用户指定对比函数,使用默认的就可以。

而对于自定义类型,需要实现一个less函数或者重载一个“<”小于操作符,例如这个例子中的自定义Dew类中包含a,b,c三个成员,比大小的规则是先对比a,如果a一样就对比b,如果b一样就对比c。

#include <iostream>
#include <set>
#include <string>
using namespace std;
class Dew
{
  public:
  
    Dew(int _a, int _b, int _c)
      : a(_a), b(_b), c(_c)
    {}
 
    bool operator<(const Dew &other) const
    {
      if (a < other.a)
        return true;
      if (a == other.a && b < other.b)
        return true;
      return (a == other.a && b == other.b && c < other.c);
    }
    int a;
    int b;
    int c;
};
 

int main()
{
 std::set<Dew> set;
 for(int i = 0; i < 16; i++)
 {
     set.emplace(i,i,i);
 }
 for (auto item : set)
 {
     cout<<item.a<<" "<<item.b<<" "<<item.c<<endl;
 }
}

再看另一种场景,如果自定义类型中没有实现<和less函数,那就需要实现一个这个类型的对比函数对象。例如:

#include <iostream>
#include <set>
#include <string>
using namespace std;
class Dew
{
  public:
  
    Dew(int _a, int _b, int _c)
      : a(_a), b(_b), c(_c){}
 
    int a;
    int b;
    int c;
};
class DewCompare
{
    public:
    bool operator ()(const Dew &a, const Dew &b)
    {
        return (a.a < b.a
                    || (a.a == b.a && a.b < b.b)
                    || (a.a == b.a && a.b == b.b && a.c < b.c));
    };
};

int main()
{
     std::set<Dew,DewCompare> set;
     for(int i = 0; i < 16; i++)
     {
         set.emplace(i,i,i);
     }
     for (auto item : set)
     {
         cout<<item.a<<" "<<item.b<<" "<<item.c<<endl;
     }
}

set中保存的是唯一对象,但是它是如何判断两个元素如何相等呢?如果两个元素都不小于对方,那么就可以判断两个元素相等:!comp(a, b) && !comp(b, a)。举个例子,假如int = 3,int b =3,那么 a < b 为false,b < a也为false,所以推出a == b。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值