STL 容器(二) set,unordered_set

文章目录

前言

set 与 unordered_set 作为最常用的关联式容器,set难点在于如何对容器中的元素进行排序,下面的内容主要对于这两个容器的排序方式做了总结。

set

set这一个容器在插入的同时便能够进行自动排序,根据元素的类型不同,我们可以控制这种排序的方式。

#include <iostream>
#include <vector>
#include <set>
#include <map>
using namespace std;

/*
1.非自定义类类型
对于如同int char 此类型在set中进行排序,直接使用std::less, std::greater就可以解决
而对于指针类型,则只能采用函数对象
*/
struct Comp1
{
    bool operator()(int *x, int *y)
    {
        return *x < *y;
    }
};

void test1()
{
    std::set<int, std::less<int>> myset{4, 3, 5, 6, 2, 7};
    for (auto &e : myset)
        cout << e << endl;
    cout << "--------------------" << endl;

    int *a1 = new int(4);
    int *a2 = new int(3);
    int *a3 = new int(5);
    set<int *, Comp1> myset2{a1, a2, a3};
    for (auto &e : myset2)
        cout << *e << endl;
    delete a1;
    delete a2;
    delete a3;
}

/*
2.自定义类类型
针对自定义的类类型 如class Point类型, 就不能再使用std::less , std::greater 之类的函数
只能够自己重载运算符< , 或是定义函数对象
*/
class Point
{
    int _x;
    int _y;
    int _multi;

public:
    Point(int x, int y) : _x(x), _y(y), _multi(_x * _y) {}
    int getMulti() const { return _multi; }
};

//方法一 重载运算符< 但注意对指针类型并不管用
bool operator<(const Point &lhs, const Point &rhs)
{
    return lhs.getMulti() < rhs.getMulti();
}

//方法二 设置函数对象
struct Comp2
{
    bool operator()(Point *lhs, Point *rhs)
    {
        return lhs->getMulti() < rhs->getMulti();
    }
};

void test2()
{
    set<Point> myset1{Point{1, 3}, Point{2, 2}, Point{1, 1}, Point{2, 1}};
    for (auto &e : myset1)
        cout << e.getMulti() << endl;
    cout << "----------------------" << endl;

    Point *p1 = new Point(2, 2);
    Point *p2 = new Point(1, 3);
    Point *p3 = new Point(3, 3);
    set<Point*, Comp2> myset2{p1, p2, p3};
    for (auto &e : myset2)
        cout << e->getMulti() << endl;
    
    delete p1;
    delete p2;
    delete p3;
}


int main()
{
    test2();
    return 0;
}

unordered_set

由于unordered_set底层仍然使用的时哈希表,所以我们在使用自定义的类类型使用时,也必须定义

  • PointHasher 哈希函数
  • PointEqual 哈希元素中的比较方式
    这两个函数
#include <iostream>
#include <functional>
#include <vector>
#include <iterator>
#include <algorithm>
#include <unordered_map>
#include <map>
#include <unordered_set>
using namespace std;

//类存放入哈希表
class Point
{
public:
    Point(int x, int y)
        : _x(x), _y(y)
    {
        _sum = x + y;
    }
    int _x;
    int _y;
    int _sum;
    friend ostream &operator<<(ostream &os, const Point &lhs);
};
ostream &operator<<(ostream &os, const Point &lhs)
{
    os << lhs._sum;
    return os;
}

//自定义 PointEqual 也就是哈希表中key元素的存放比较
struct PointEqual{
    bool operator()(const Point& lhs, const Point& rhs)const{
        return (lhs._x==rhs._x) && (lhs._y==rhs._y);
    }
};


//自定义PointHasher 也就是哈希函数
struct PointHasher
{
	size_t operator()(const Point & rhs) const
	{
		return ((rhs._x * rhs._x) >> 1) ^
				((rhs._y * rhs._y) >> 1);
	}
};



int main(){
    unordered_set<Point, PointHasher, PointEqual> myhashmap;
    myhashmap.insert(Point(1,1));
    myhashmap.insert(Point(2,1));
    myhashmap.insert(Point(3,1));

    //因为是hash表的方式存储,所以其实是无序的
    for (auto &e : myhashmap)
        cout << e._x << "," << e._y << endl;
    return 0;
}


  • 1
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页
评论

打赏作者

Worthy_Wang

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值