文章目录
前言
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;
}