# STL set 自定義排序

### set

set這一個容器在插入的同時便能夠進行自動排序，根據元素的類型不同，我們可以控制這種排序的方式。

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

/*
1.非自定義類類型

*/
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
{
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

• 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;
}

``````