干净的方式迭代集合的联合?

时间:2014-12-21 21:35:19

标签: c++ stl

我有2个std :: set实例,例如,一个实例对应于时间t的集合状态,另一个实例对应于t + 1。

我想迭代这两组的联合(在数学意义上),这样:

  • 联合的每个元素都会被处理一次
  • 对于每个元素我可以在恒定时间内判断它是在第一组,第二组还是两者中

以下是我目前正在做的一个例子:

std::set<A> old_set, new_set;
for(auto it = old_set.begin(); it != old_set.end(); ++it) {
        if(new_set.count(*it) == 0) {
            //only in old set but not in new set
        }
    }

for(auto it = new_set.begin(); it != new_set.end(); ++it) {
    if(old_set.count(*it) == 0) {
        //only in new set but not in old set
    }
}

正如您所看到的,它缺少我们处理两个集合中元素的部分,而且复杂性也不够好。我认为应该有一种方法可以通过简单地迭代集合

的所有元素来做我想要的

有没有人有想法?

由于

3 个答案:

答案 0 :(得分:4)

您可以执行以下操作:

template <typename T, typename D>
void iterate(std::set<T>& s1, std::set<T>& s2, D d)
{
    auto it1 = s1.begin();
    auto it2 = s2.begin();

    while (it1 != s1.end() && it2 != s2.end()) {
        if (*it1 < *it2) {
            // only in set1
            d.visit1(*it1);
            ++it1;
        } else if (*it2 < *it1) {
            // only in set2
            d.visit2(*it2);
            ++it2;
        } else {
            // in both
            d.visitboth(*it1, *it2);
            ++it1;
            ++it2;
        }
    }
    for (; it1 != s1.end(); ++it1) {
        // only in set1
        d.visit1(*it1);
    }
    for (; it2 != s2.end(); ++it2) {
        // only in set2
        d.visit2(*it2);
    }
}

答案 1 :(得分:0)

在完成所有计算之后,在std::vector这样的快速容器中创建联合并迭代它可能更有效:

int main()
{
    std::set<int> s1 {1, 2, 4, 6, 9};
    std::set<int> s2 {2, 3, 4, 6, 11};

    std::vector<int> u;

    u.reserve(s1.size() + s2.size());

    std::set_union(s1.begin(), s1.end(), s2.begin(), s2.end()
        , std::back_inserter(u));

    for(auto it = u.begin(); it != u.end(); ++it)
    {
        // do stuff on union
        std::cout << "u: " << *it << '\n';
    }
}

答案 2 :(得分:0)

一个想法是编写自己的迭代器,它可以对容器执行迭代并以这种方式合并它们:

template<typename... T>
class MergeIterator{
 MergeIterator( T... constainers ):m_containers(std::forward(containers)...){}
 std::tuple< T... > m_containers;
 /// implement the operators here.
 MergeIterator operator ++(){///... here switch the tuple if needed until it is not on the last element}
};

为简单起见,您可以使用std :: vector&lt; ContainerType&gt;而不是元组和T作为容器中的变量类型。 我不确定在增强版或其他库中是否有可用的内容......

What's the best way to iterate over two or more containers simultaneously