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