STL set 自定義排序

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章