如何找到 n 向量的并集?
How to find union of n vector?
我有一个二维超边向量和一个邻接表。我必须找到 hyperEdges[i].size()
向量的并集,但我只能找到两个向量的并集。我可以对下面的代码做哪些改进来做到这一点?
我想将并集存储到新声明的二维向量中 connectedEdges
void find_union()
{
connectedEdges.resize(nEdges+1);
for(int i = 1; i <= nEdges; i++)
{
vector<int>::iterator it;
connectedEdges[i].resize(nEdges+1);
for(int j = 1; j < hyperEdges[i].size()-1; j++)
{
int p = hyperEdges[i][j-1];
int q= hyperEdges[i][j];
it = set_union(adjL[p].begin(), adjL[p].end(),adjL[q].begin(),adjL[q].end(), connectedEdges[i].begin());
connectedEdges[i].resize(it-connectedEdges[i].begin());
}
}
}
示例:
{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}
但是我的程序returns{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());
您可以将它们移动到 set
中,然后按照 的建议退出。或者您可以直接手动迭代所有这些:
#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
}
// 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
}
我有一个二维超边向量和一个邻接表。我必须找到 hyperEdges[i].size()
向量的并集,但我只能找到两个向量的并集。我可以对下面的代码做哪些改进来做到这一点?
我想将并集存储到新声明的二维向量中 connectedEdges
void find_union()
{
connectedEdges.resize(nEdges+1);
for(int i = 1; i <= nEdges; i++)
{
vector<int>::iterator it;
connectedEdges[i].resize(nEdges+1);
for(int j = 1; j < hyperEdges[i].size()-1; j++)
{
int p = hyperEdges[i][j-1];
int q= hyperEdges[i][j];
it = set_union(adjL[p].begin(), adjL[p].end(),adjL[q].begin(),adjL[q].end(), connectedEdges[i].begin());
connectedEdges[i].resize(it-connectedEdges[i].begin());
}
}
}
示例:
{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}
但是我的程序returns{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());
您可以将它们移动到 set
中,然后按照
#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
}
// 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
}