【问题标题】:How to get (unordered) set difference or symmetric difference in C++?如何在 C++ 中获得(无序)集合差异或对称差异?
【发布时间】:2020-05-17 08:51:39
【问题描述】:

我无法从文档中推断我可以使用std::set_difference,因为它说集合应该是有序的,这意味着它们不是集合,而是列表。此外,所有示例都是关于有序列表,而不是集合。

如何知道真相?

【问题讨论】:

    标签: c++ set set-difference


    【解决方案1】:

    std::set_difference 用于任意排序的输入(预排序的std::vectors、std::lists、std::deques、普通数组等),它恰好适用于std::set(其中也已排序)。

    如果您正在使用std::unordered_set(或std::set,并且您可以就地操作),您只需使用erase 方法从一个这样的集合中删除所有元素到另一个获取差异,例如:

    for (const auto& elem : set_to_remove) {
        myset.erase(elem);
    }
    

    你也可以把它做成一个新的集合with std::copy_if;那里的配方非常适用于对称差异的情况(它只是对std::copy_if 的两次调用,其中每个调用在一个输入集上运行,并且以其他输入集中不存在的元素为条件)。

    【讨论】:

    • 此示例中的代码会导致段错误。 std::set::erase 的这种用法仅适用于 属于 myset 的迭代器。参见here:“删除[first; last) 范围内的元素,该范围必须是*this 中的有效范围。”
    • @sasquires:哎呀,我的错。它没有那么优雅,但我用一个只迭代set_to_remove 并使用erase 的按值版本的版本替换了坏代码。感谢您接听!
    【解决方案2】:

    std::set 已排序。查看docs

    std::set 是一个关联容器,其中包含 一个排序集 Key 类型的唯一对象。排序是使用键比较完成的 功能比较。搜索、删除和插入操作 对数复杂度。集合通常实现为红黑 树。

    因此,您可以像使用任何其他提供所需接口的容器一样使用它。 std::set 和 e.g. 之间的区别std::vectorstd::set 在插入时对其元素进行排序,如果是 std::vector,您需要使用 std::sort 函数对其元素进行排序。

    例如,如果您需要std::set_differencestd::unordered_set,您可以这样做:

    #include <set>
    #include <iostream>
    #include <algorithm>
    #include <unordered_set>
    
    int main() {
        std::unordered_set<int> a {3, 1, 4, 6, 5, 9};
        std::unordered_set<int> b {3, 1, 4};
    
        std::set<int> c;
        std::set<int> d;
        std::copy(a.begin(), a.end(), std::inserter(c, c.end()));
        std::copy(b.begin(), b.end(), std::inserter(d, d.end()));
    
        std::vector<int> diff;
    
        std::set_difference(c.begin(), c.end(), d.begin(), d.end(), 
                            std::inserter(diff, diff.begin()));
    
        for (auto const i : diff)
            std::cout << i << ' ';
    
        return 0;
    }
    

    live

    【讨论】:

    • 所以我需要无序集。
    猜你喜欢
    • 2019-06-15
    • 2014-10-05
    • 2021-08-16
    • 2016-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-18
    • 1970-01-01
    相关资源
    最近更新 更多