【问题标题】:nesting c++11 range loops for finding combinations嵌套 c++11 范围循环以查找组合
【发布时间】:2012-09-11 21:43:37
【问题描述】:

寻找组合涉及同一容器上的两个循环。

the first iterates over elements:
  pick an element
  iterate over the elements on the left
    print the first and the second iterated elements

所以这是一个错误的例子:

vector<int> vec;
for(size_t i=0; i< 10 ; ++i) vec.push_back(i);
for(auto i : vec)
{
  auto j = i.increaseBy(1);
  for(j : vec) cout << i << j << "\n";
}

在这个问题中,我感兴趣的是范围循环的语法是否不仅仅是一种简单的迭代元素的方法。没有太多关于 c++11 的文档。

【问题讨论】:

  • 它用于迭代容器的所有元素。您无法定义自己的起点或终点。

标签: c++ for-loop c++11 iterator combinations


【解决方案1】:

假设您想要遍历 [(v[i], v[j]) | i &lt;- [0..v.size()], j &lt;- [0..i]](使用具有列表理解语法的伪代码),那么您可以在 Boost.Range 的帮助下执行以下操作:

for(auto i: boost::irange(0, v.size()))
    for(auto j: boost::irange(0, i)) {
        // use v[i] and v[j]
    }

不过,除了示例之外,您的问题的答案是不,range-for 语句并没有什么魔力。它也是不可扩展的。然而,好消息是还有另一种看待它的方式:range-for 语句可能非常愚蠢,但范围可以随心所欲。

这意味着虽然 range-for 可能只能迭代一个范围的元素,但该范围没有例如映射到实际的现有容器,这与您的预期相反。比如这个

namespace A = boost::adaptors;
for(auto&& e: A::strided(v, 2)) foo(e);

v 的每个其他元素上调用foo。这里的工作是由 strided 完成的,而不是 range-for 语句。

即使在 Boost.Range 的帮助下,我也想不出一种简洁的方式来仅在一个范围内表达您的示例。但这并不意味着它是不可能的,而且我过去确实研究过 C++ 中某种形式的列表理解。然而,表达它的工具今天不在这里。

【讨论】:

  • +1 非常好。一切都与范围有关 :-) 我想,Boost 所缺少的只是一种“产品范围”。
  • @KerrekSB 是的。你已经可以过滤和转换了,通过迭代器表达笛卡尔积确实是我尝试时的一大障碍。
  • 我想你需要对迭代器类别有更严格的要求......现有的范围适配器可能都设法保留了该类别。
  • @KerrekSB Boost.Range 位于 Boost.Iterators 之上,其中确实包含扩展/改进当前迭代器(准)概念的提议。
  • 完成,#include &lt;boost/range/irange.hpp&gt; 我刚刚做了for(auto i:v) for(auto j:boost::irange(i,v.size())) { cout &lt;&lt; i &lt;&lt; j;} 谢谢
【解决方案2】:

我猜你想要的是一组 pairs 矢量元素的集合。

这不是基于范围的循环的用途。基于范围的循环用于遍历整个集合,只查看每个元素一次。不要将它们用于其他任何事情。仅仅因为它是一个新的、添加的语言功能并不意味着你必须抛弃你曾经知道的所有其他东西。新功能丰富语言,他们不会替换它。

以下是获取唯一对的方法:

for (auto it1 = vec.begin(), end = vec.end(); it1 != end; ++it1)
{
     for (auto it2 = std::next(it1); it2 != end; ++it2)
     {
         std::cout << "[" << *it1 << ", " << *it2 << "]\n";
     }
}

如果您还想包含对角线元素 (it1, it1),只需将第二个初始化替换为 auto it2 = it1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-08
    • 2022-08-17
    • 1970-01-01
    • 2012-02-16
    • 2021-09-14
    • 1970-01-01
    相关资源
    最近更新 更多