简体   繁体   English

C ++ std :: set和std :: multiset

[英]C++ std::set and std::multiset

In C++ by default both std::set and std::multiset have std::less<T> as their comparator. 在C ++中,默认情况下std::setstd::multiset都有std::less<T>作为比较器。 Can anyone please explain how does std::multiset allow duplicates and std::set does not? 任何人都可以解释std::multiset如何允许重复和std::set不?

Both start with the equivalent an upper_bound on the existing contents to find the correct insertion point for the new item. 两者都从现有内容的等效upper_bound开始,以找到新项目的正确插入点。

std::set then checks whether that found an existing item with a key equal to the new key, and if so returns, signaling failure. 然后, std::set检查是否找到了一个密钥等于新密钥的现有项,如果返回,则表示信令失败。

std::multiset just inserts the new item at that point (and if it didn't return in the step above, std::set does the same). std::multiset只是在那一点插入新项目(如果它没有在上面的步骤中返回, std::setstd::set )。

To follow up on Jerry's answer, note that std::set and std::multiset assume that the elements are comparable via a strict weak ordering by operator< . 为了跟进Jerry的答案,请注意std::setstd::multiset假设元素可以通过operator<严格弱排序进行比较。 In particular, the elements do not have to be comparable under operator== . 特别是,元素不必在operator==下具有可比性 std::set only allows non-equivalent elements, whereas std::multiset allows in addition equivalent elements. std::set仅允许非等效元素,而std::multiset允许添加等效元素。 This is slightly different from equality/non-equality. 这与平等/不平等略有不同。 Two elements A and B are equivalent whenever !(A < B) && !(B < A) , and it is this latter condition that is checked by std::set::insert , and if true, the element is not inserted. 每当!(A < B) && !(B < A) ,两个元素AB是等价的,后一个条件由std::set::insert检查,如果为true,则不插入元素。

Example Live on Ideone 示例Live on Ideone

#include <iostream>
#include <set>

struct Foo
{
    int _x, _y, _z;
    Foo(int x, int y, int z): _x(x), _y(y), _z(z) {}
    bool operator<(const Foo& rhs) const // weak majorization
    {
        return (_x < rhs._x) && (_x + _y < rhs._x + rhs._y) &&
               (_x + _y + _z < rhs._x + rhs._y + rhs._z) ; 
    }
};

int main()
{
    std::set<Foo> setFoo;
    // try to insert 2 equivalent elements
    setFoo.insert(Foo{1, 2, 3}); 
    if(setFoo.insert(Foo{1, 2, 0}).second == false) // failed to insert
        std::cout << "Equivalent element already in the set!" << std::endl;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM