在迭代期间更改集合的最佳方法是什么?
What is the best way to change a set during iterations?
给定 std::set
,在时间迭代期间更改集合的最佳方法是什么?
例如:
std::set<T> s; // T is a some type (it's not important for the question).
// insertions to s
for (std::set<T>::iterator it = s.begin(); it != s.end(); it++) {
T saveIt(*it);
s.erase(*it);
s.insert( saveIt + saveIt ); // operator+ that defined at `T`
}
根据我在某些资料中读到的内容,这是一种糟糕的方式,因为:从集合中移除可能会改变集合的结构。
那么更好(/最好)的方法是什么?
您的循环可能会导致几乎无休止的循环,因为您不断在集合的后面添加更大的元素。直到 T + T
溢出。
正确的方法是创建一个新集合:
std::set<T> s;
std::set<T> s2;
for(auto const& elem : s)
s2.insert(elem + elem);
s.swap(s2);
和boost::range
是单行的:
#include <boost/range/adaptor/transformed.hpp>
// ...
std::set<int> s;
s = boost::copy_range<std::set<int>>(s | boost::adaptors::transformed([](int x) { return x + x; }));
只需要一份std:set
std::set<T> s;
std::set<T> modified_s;
for (std::set<T>::iterator it = s.begin(); it != s.end(); it++) {
modified_s.insert(*it+ *it);
}
s = std::move(modified_s);
编辑:
添加了 std::move
作为@Jodocus
的改进
给定 std::set
,在时间迭代期间更改集合的最佳方法是什么?
例如:
std::set<T> s; // T is a some type (it's not important for the question).
// insertions to s
for (std::set<T>::iterator it = s.begin(); it != s.end(); it++) {
T saveIt(*it);
s.erase(*it);
s.insert( saveIt + saveIt ); // operator+ that defined at `T`
}
根据我在某些资料中读到的内容,这是一种糟糕的方式,因为:从集合中移除可能会改变集合的结构。
那么更好(/最好)的方法是什么?
您的循环可能会导致几乎无休止的循环,因为您不断在集合的后面添加更大的元素。直到 T + T
溢出。
正确的方法是创建一个新集合:
std::set<T> s;
std::set<T> s2;
for(auto const& elem : s)
s2.insert(elem + elem);
s.swap(s2);
和boost::range
是单行的:
#include <boost/range/adaptor/transformed.hpp>
// ...
std::set<int> s;
s = boost::copy_range<std::set<int>>(s | boost::adaptors::transformed([](int x) { return x + x; }));
只需要一份std:set
std::set<T> s;
std::set<T> modified_s;
for (std::set<T>::iterator it = s.begin(); it != s.end(); it++) {
modified_s.insert(*it+ *it);
}
s = std::move(modified_s);
编辑:
添加了 std::move
作为@Jodocus