迭代集合并集的干净方法

clean way to iterate over union of sets ?

本文关键字:方法 集合 合并 迭代      更新时间:2023-10-16

我有 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
    }
}

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

有人有想法吗?

谢谢

你可以做这样的事情:

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);
    }
}

在所有这些计数之后,在快速容器(如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';
    }
}

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

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 而不是元组和 T 作为容器中的变量类型。我不确定提升或其他库中是否已经有一些东西......

同时迭代两个或多个容器的最佳方法是什么