如何迭代 unordered_set 中的无序对?
How to iterate on unordered pairs inside an unordered_set?
迭代 unordered_set
中的无序元素对的简洁方法是什么?
(所以顺序无关紧要,元素应该不同)
e.g. {1, 2, 3} => (1, 2) (2, 3) (1, 3)
我最初的尝试是这样的
for (i = 0; i < size - 1; i++) {
for (j = i + 1; j < size; j++) {
...
}
}
但是对于迭代器来说这不是超级方便。
这应该有效,给定 std::unordered_set
s
:
auto set_end = s.end();
for (auto ai = s.begin(); ai != set_end; ++ai) {
for (auto bi = std::next(ai); bi != set_end; ++bi) {
// *ai, *bi
}
}
这基本上是等价于以下整数的迭代器:
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
// i, j
}
}
这是 orlp 的 semi-generic 形式的解决方案。
template<typename ForwardIterator, typename DestItr>
auto cartesian_product(ForwardIterator b, ForwardIterator e, DestItr d) -> DestItr {
using std::next;
using std::for_each;
for (; b != e; ++b) {
for_each(next(b), e, [&](auto right){
*d++ = std::make_tuple(*b, right);
});
}
return d;
}
template<typename ForwardRange, typename DestItr>
auto cartesian_product(ForwardRange r, DestItr d) -> DestItr {
using std::begin;
using std::end;
return cartesian_product(begin(r), end(r), d);
}
当然,您可以通过重载自定义仿函数来代替 make_tuple
和赋值运算符,从而使其更通用。标准库算法倾向于这样做。如果我为图书馆写这篇文章,我可能也会这样做。
迭代 unordered_set
中的无序元素对的简洁方法是什么?
(所以顺序无关紧要,元素应该不同)
e.g. {1, 2, 3} => (1, 2) (2, 3) (1, 3)
我最初的尝试是这样的
for (i = 0; i < size - 1; i++) {
for (j = i + 1; j < size; j++) {
...
}
}
但是对于迭代器来说这不是超级方便。
这应该有效,给定 std::unordered_set
s
:
auto set_end = s.end();
for (auto ai = s.begin(); ai != set_end; ++ai) {
for (auto bi = std::next(ai); bi != set_end; ++bi) {
// *ai, *bi
}
}
这基本上是等价于以下整数的迭代器:
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
// i, j
}
}
这是 orlp 的 semi-generic 形式的解决方案。
template<typename ForwardIterator, typename DestItr>
auto cartesian_product(ForwardIterator b, ForwardIterator e, DestItr d) -> DestItr {
using std::next;
using std::for_each;
for (; b != e; ++b) {
for_each(next(b), e, [&](auto right){
*d++ = std::make_tuple(*b, right);
});
}
return d;
}
template<typename ForwardRange, typename DestItr>
auto cartesian_product(ForwardRange r, DestItr d) -> DestItr {
using std::begin;
using std::end;
return cartesian_product(begin(r), end(r), d);
}
当然,您可以通过重载自定义仿函数来代替 make_tuple
和赋值运算符,从而使其更通用。标准库算法倾向于这样做。如果我为图书馆写这篇文章,我可能也会这样做。