【问题标题】:C++ std::set and std::multisetC++ std::set 和 std::multiset
【发布时间】:2015-08-01 02:12:44
【问题描述】:

在 C++ 中,std::setstd::multiset 默认将 std::less<T> 作为比较器。谁能解释一下std::multiset 如何允许重复而std::set 不允许?

【问题讨论】:

    标签: c++ set containers std multiset


    【解决方案1】:

    两者都以现有内容上的等效 upper_bound 开头,以找到新项目的正确插入点。

    std::set 然后检查它是否找到了一个现有项目,其密钥等于新密钥,如果是,则返回,表示失败。

    std::multiset 只是在该点插入新项目(如果在上述步骤中没有返回,std::set 也会这样做)。

    【讨论】:

    • 我认为 std::set 正在检查等价性,而不是等价性,不是吗?特别是,可以使用只定义operator<(严格弱排序)的类型,而不是operator==
    • 这是否意味着upper_bound的返回值可以有效地作为insert的提示?
    • @Lingxi 可能,但它不会提高插入所需的比较总数,因为您为upper_bound 付费。
    【解决方案2】:

    要跟进 Jerry 的回答,请注意 std::setstd::multiset 假设这些元素可通过 strict weak orderingoperator< 进行比较。特别是,元素不必在operator== 下具有可比性std::set 只允许 non-equivalent 元素,而std::multiset 允许另外 equivalent 元素。这与平等/不平等略有不同。两个元素AB!(A < B) && !(B < A) 时是等价的,std::set::insert 检查的是后一种条件,如果为真,则不插入元素。

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

    【讨论】:

      猜你喜欢
      • 2021-06-01
      • 1970-01-01
      • 2019-02-14
      • 2015-10-27
      • 2014-08-07
      • 1970-01-01
      • 2011-12-29
      • 2014-04-15
      • 1970-01-01
      相关资源
      最近更新 更多