多组的对称差异

时间:2014-11-27 17:13:04

标签: c++ templates set

集合的对称差异是不属于所有集合的所有元素的集合。如果集合已经排序,那么我想出了下面使用std :: set_union,std :: set_intersection和std :: set_difference的解决方案。但我不相信这是最干净的方法。有人会想到一种更好的(也许是更有效的)方法,它使用一个带有可变参数模板参数的简单递归来立即获得结果吗?也许递归使用std :: set_symmetric_difference?我很难搞清楚这一点。以下是使用上述方法的解决方案:

#include <iostream>
#include <vector>
#include <algorithm>

template <typename Container>
std::vector<typename Container::value_type> multi_union (const Container& container) {
    return container;
}

template <typename Container1, typename Container2, typename... Containers>
std::vector<typename Container1::value_type> multi_union (const Container1& container1,
const Container2& container2, const Containers&... containers) {
    std::vector<typename Container1::value_type> v;
    std::set_union (container1.begin(), container1.end(), container2.begin(), container2.end(),
        std::back_inserter(v));
    return multi_union (v, containers...);
}

template <typename Container>
std::vector<typename Container::value_type> multi_intersection (const Container& container) {
    return container;
}

template <typename Container1, typename Container2, typename... Containers>
std::vector<typename Container1::value_type> multi_intersection (const Container1& container1,
const Container2& container2, const Containers&... containers) {
    std::vector<typename Container1::value_type> v;
    std::set_intersection (container1.begin(), container1.end(), container2.begin(),
        container2.end(), std::back_inserter(v));
    return multi_intersection (v, containers...);
}

template <typename Container, typename... Containers>
std::vector<typename Container::value_type> multi_symmetric_difference (const Container&
container, const Containers&... containers) {
    const std::vector<typename Container::value_type>
        a = multi_union (container, containers...),
        b = multi_intersection (container, containers...);
    std::vector<typename Container::value_type> v;
    std::set_difference (a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(v));
    return v;
}

int main() {
    std::vector<int> a = {3,4,6,1,2},  b = {6,8,9,2}, c = {6,7,4,5,2};
    std::sort (a.begin(), a.end());  std::sort (b.begin(), b.end());  std::sort (c.begin(), c.end());
    const std::vector<int> s = multi_symmetric_difference (a, b, c);
    for (int x : s) std::cout << x << ' ';  // 1 3 4 5 7 8 9
}

此外,与std :: set_symmetric_difference一样,multi_symmetric_difference应输出到输出迭代器,以便生成的容器可以是任何类型(不仅仅是向量)。

0 个答案:

没有答案