C++ 如何求n向量的并集?

C++ 如何求n向量的并集?,c++,vector,set-union,C++,Vector,Set Union,我有一个超边的二维向量和一个邻接列表。我必须找到超边[I]的并集。大小向量,但我只能找到两个向量的并集。为了做到这一点,我可以对下面的代码进行哪些改进? 我想将并集存储到新声明的二维向量connectedges中 例如: {1,2,4,6,8} {1,2,3,5,6} {1,4,7,13,15} 这三个集合的并集应该是{1,2,3,4,5,6,7,8,13,15} 但是我的程序返回{1,2,3,4,5,6,8}如果有很多向量,我建议将所有向量的内容插入单个std::set,然后将其转储回std:

我有一个超边的二维向量和一个邻接列表。我必须找到超边[I]的并集。大小向量,但我只能找到两个向量的并集。为了做到这一点,我可以对下面的代码进行哪些改进? 我想将并集存储到新声明的二维向量connectedges中

例如: {1,2,4,6,8}

{1,2,3,5,6}

{1,4,7,13,15}

这三个集合的并集应该是{1,2,3,4,5,6,7,8,13,15}
但是我的程序返回{1,2,3,4,5,6,8}

如果有很多向量,我建议将所有向量的内容插入单个std::set,然后将其转储回std::vector

诸如此类:

std::vector<std::vector<int>> src = ...;
std::set<int> all;

for(int i = 0; i < src.size(); i++) {
    all.insert(src[i].begin(), src[i].end());
}

std::vector<int> result(all.begin(), all.end());

你可以按照建议将它们移动到一组中,然后再返回。或者,您可以直接手动迭代所有这些文件:

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

std::vector<int> find_union(const std::vector<std::vector<int>>& vecs)
{
    using iter = std::vector<int>::const_iterator;
    using pr = std::pair<iter, iter>;

    // construct pairs of iterators into each vector
    // we will iterate over all of these simultaneously
    std::vector<pr> iter_pairs;
    std::vector<int> results;

    iter_pairs.reserve(vecs.size());
    for (auto& v : vecs) {
        iter_pairs.emplace_back(v.begin(), v.end());
    }   

    while (!iter_pairs.empty()) {
        // pick the next smallest element
        int m = *std::min_element(iter_pairs.begin(), iter_pairs.end(), [](const pr& a, const pr& b){ 
                    return *a.first < *b.first;
                })->first;

        // add it to our results
        results.push_back(m);

        // any vector that contained this element should be advanced
        // if we're done with that vector, remove it
        iter_pairs.erase(
            std::remove_if(iter_pairs.begin(), iter_pairs.end(), [=](pr& p){ 
                if (*p.first == m) {
                    ++p.first;
                    return p.first == p.second;
                }   
                return false;
            }), 
            iter_pairs.end()
            );  
    }   

    return results;
}

int main() {
    for (int i : find_union({{1,2,3}, {1,2,4}, {3,5,42}})) {
        std::cout << i << ' '; // prints 1 2 3 4 5 42
    }   
    std::cout << std::endl;
}
您还可以对所有相邻向量运行std::set_union,确保它们已排序,并逐步生成结果,如以下示例所示:

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

int main()
{
    std::vector<std::vector<int>> v{{1, 1, 2}, {1, 1, 1}, {1, 5, 6, 7}};       
    std::vector<int> result, tmp;
    for(auto&& elem: v)
    {
        std::set_union(elem.begin(), elem.end(), 
                       result.begin(), result.end(),
                       std::back_inserter(tmp));
        result = std::move(tmp); 
        tmp.clear(); // see http://stackoverflow.com/q/9168823/3093378
    }
    // in case you want to remove duplicates
    result.erase(std::unique(result.begin(), result.end()), result.end());
    for(auto&& elem: result)
        std::cout << elem << " "; // 1 2 5 6 7
}

你到底有什么问题?什么不起作用?@inf:我的问题是,它只存储两个向量的并集,我想在这里存储hypeEdges[i].size向量的并集。你的问题很不清楚。你想找到两个向量的并集吗?或者您能够找到两个向量的并集并尝试找到多个向量的并集吗?您可以使用调试器或print语句来验证set_union是否返回您希望它返回的结果?我不明白调整大小是怎么回事,但看起来很奇怪。@Beta:我想找到两个以上向量的并集。我建议使用swap将结果复制到tmp中。当前版本似乎无效,因为您移动到刚刚创建的结果中…@anxieux我回滚了编辑,必须修改一点swap/move的代码。将在正确时更新。现在完成。但就效率和简单性而言,您的答案在这里可能是最合适的。您的算法在std::vector v{{{1,1,1},{1,1,1},{1,1,1}时失败@anxieux我想这回答了我们的问题:谢谢,这就是我想要的:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

int main()
{
    std::vector<std::vector<int>> v{{1, 1, 2}, {1, 1, 1}, {1, 5, 6, 7}};       
    std::vector<int> result, tmp;
    for(auto&& elem: v)
    {
        std::set_union(elem.begin(), elem.end(), 
                       result.begin(), result.end(),
                       std::back_inserter(tmp));
        result = std::move(tmp); 
        tmp.clear(); // see http://stackoverflow.com/q/9168823/3093378
    }
    // in case you want to remove duplicates
    result.erase(std::unique(result.begin(), result.end()), result.end());
    for(auto&& elem: result)
        std::cout << elem << " "; // 1 2 5 6 7
}