使用正确的find()创建有序多重集

时间:2018-08-22 15:05:53

标签: c++ c++11

我尝试使用以下代码创建有序多集:

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;

template <class type1>
using ordered_multiset = tree <type1, null_type, less_equal <type1>, rb_tree_tag, tree_order_statistics_node_update>;

ordered_multiset <ll> kek;

int main()
{
    kek.insert(1); kek.insert(1);
    kek.insert(2); kek.insert(2); kek.insert(2);
    kek.insert(3);
    cout << (kek.find(2) == kek.end()) << endl;
}

但是find()找不到任何数字,因为使用了less_equal < ll >比较器而不是less < ll >。那么,如何使用工作权限find()将排序形式的重复项保存下来?

1 个答案:

答案 0 :(得分:0)

从gnu文档here

  

大括号:该库不包含类似   std :: multimap或std :: multiset。相反,这些数据结构可以是   通过操作“映射的模板”参数合成。

如果没有您自己的样板,就无法对多集使用此数据结构。例如,您可能会执行以下操作(尽管这是不安全的不完整实现)

template <class T>
class multiset_equal_list {
    friend operator<(const multiset_equal_list<T>&, const T&);
private:
    mutable std::vector<T> equals;
public:
    bool operator<(const T& arg) const { return equals[0] < arg; }
    void add_equal(const T& arg) const { equals.push_back(arg); }
}


template <class T>
class my_multiset {
private:
    std::set<multiset_equal_list<T>> values; //instead of set, you can use the __gnu_pbds tree
public:
    void insert(const T& arg) {
        auto it = values.lower_bound(arg);
        if (it == values.end() || (*it < arg)) {
            multiset_equal_list<T> to_add;
            to_add.add_equal(arg);
            values.insert(it, to_add);
        } else { //they are equal
            it->add_equal(arg);
        }
    }
}

该链接更多地介绍了如何以不同的方式解决问题,但是您最好自己滚动或使用现有的库,该库以更可移植的标准方式提供您想要的所有功能。

请注意,使用std::less_equal的原因对您不起作用是因为tree(以及setmultiset等)确定比较是否对等都为假。例如。如果a,则b等效于!(a < b) && !(b < a)。因此,使用less_equal绝不可能(禁止过载)