遍历 std::set 中包含的所有三重不同值?
Go through all triple of different values contained in a std::set?
假设我有一个没有重复值的排序向量。如果我想遍历不同值的所有三元组,我这样做:
for(std::size_t i = 0; i < data.size(); ++i)
for(std::size_t j = i+1; j < data.size(); ++j)
for(std::size_t k = j+1; k < data.size(); ++k)
do_somthing_with(data[i],data[j],data[k]);
如果我的容器是std::set
,如何使用迭代器执行此操作?
注意:出于兼容性原因,我不使用 C++11。
你可以做与向量几乎相同的操作,但你需要创建一个包装函数,它将复制和递增集合迭代器:
std::set<int>::const_iterator next_iterator(std::set<int>::const_iterator it)
{
return ++it; // it has been passed by value, so already copied
}
//...
for (std::set<int>::const_iterator it = data.begin(); it != data.end(); ++it)
for(std::set<int>::const_iterator jt = next_iterator(it); jt != data.end(); ++jt)
for(std::set<int>::const_iterator kt = next_iterator(jt); kt != data.end(); ++kt)
// ...
你可以做这样的事情:
if (data.size() < 2) { return; }
for (auto it1 = data.begin(); it1 != std::prev(data.end(), 2); ++it1) {
for (std::size_t it2 = std::next(it1); it2 != std::prev(data.end()); ++it2) {
for (std::size_t it3 = std::next(it2); it3 != data.end(); ++it3) {
do_something_with(*it1, *it2, *it3);
}
}
}
您可以缓存std::prev
的值。
这是从一组 n 个元素中选择所有 k 组合的特例。
有关解释,请参见此处:https://en.wikipedia.org/wiki/Combination
这在之前的堆栈溢出上已经得到了回答: 在C++中创建 n 个项目的所有可能的 k 组合
你可以把你的问题想象成你必须在向量示例中使用迭代器而不是索引。让我们以这种方式简化它:
for(std::size_t i = 0; i < data.size(); ++i)
do_somthing_with(data[i]);
你可以用迭代器这样写它:
for(std::vector<MyClass>::iterator it = data.begin(); it != data.end(); ++it)
do_somthing_with(*it);
现在对集合执行相同的操作非常简单:
for(std::set<MyClass>::iterator it = data.begin(); it != data.end(); ++it)
do_somthing_with(*it);
如果你想使用三重循环,在我看来,问题从下一个迭代器开始。使用 C++11,您可以使用 std::next,但由于您不能,您需要存储迭代器,然后推进它:
for(std::set<MyClass>::iterator it1 = data.begin(); it1 != data.end(); ++it1)
{
std::set<MyClass>::iterator it2 = it1;
++it2;
for(; it2 != data.end(); ++it2)
{
std::set<MyClass>::iterator it3 = it2;
++it3;
for(; it3 != data.end(); ++it3)
do_somthing_with(*it1,*it2,*it3);
}
}
或者,您可以定义自己的next
函数,例如:
template<class ForwardIt>
ForwardIt next(ForwardIt it)
{
return ++it;
}
这基本上是 std::next 建议实现的简化版本。
然后可以更轻松地重写代码:
for(std::set<MyClass>::iterator it1 = data.begin(); it1 != data.end(); ++it1)
for(std::set<MyClass>::iterator it2 = next(it1); it2 != data.end(); ++it2)
for(std::set<MyClass>::iterator it3 = next(it2); it3 != data.end(); ++it3)
do_somthing_with(*it1,*it2,*it3);
你可以从中创建一个向量,然后按照你通常的方式去做。
std::set<int> s = {1, 2, 3, 4, 5, 6, 7};
std::vector<int> data(s.begin(), s.end());
for(std::size_t i = 0; i < data.size(); ++i)
for(std::size_t j = i+1; j < data.size(); ++j)
for(std::size_t k = j+1; k < data.size(); ++k)
do_somthing_with(data[i],data[j],data[k]);
相关文章:
- 毕达哥拉斯三重嵌套循环误解
- 遍历 std::set 中包含的所有三重不同值?
- 如何动态分配由三重指针到类的矩阵?
- 如何在C++中进行耗时的三重组合
- 删除BST节点:三重故障
- 启用中断时QEMU三重故障
- 如何修复我的 c++ 毕达哥拉斯三重查找器中的'access violation reading location'错误?
- 三重限制的正整数组合的非递归枚举
- 如何在三重运算符的帮助下通过最大值完成地图
- 三重继承,没有唯一的最终覆盖者
- C 避免使用三重指针
- 叮叮当当:"没有可用的目标与这三重兼容
- 复制一个三重嵌套容器
- 在 C 编程中可以有三重减号吗?什么意思
- 几何库中算法和数据的分离(需要三重调度?)
- 为什么我的三重对象被破坏了
- 三重与号"&&&"在C++中代表什么?
- 三重 AND("&& &")如何工作?
- 三重地图,包括2个关键点
- 解引用双指针、三重指针等等