我有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
}
}
正如您所看到的,它缺少我们处理两个集合中元素的部分,而且复杂性也不够好。我认为应该有一种方法可以通过简单地迭代集合
的所有元素来做我想要的有没有人有想法?
由于
答案 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