C++ 如何求n向量的并集?
我有一个超边的二维向量和一个邻接列表。我必须找到超边[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}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:
但是我的程序返回{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
}