代码之家  ›  专栏  ›  技术社区  ›  Armen Tsirunyan

在向量上逆方向迭代

  •  32
  • Armen Tsirunyan  · 技术社区  · 14 年前

    我需要在一个向量上从头到尾迭代。正确的方法是

    for(std::vector<SomeT>::reverse_iterator rit = v.rbegin(); rit != v.rend(); ++rit)
    {
        //do Something
    }
    

    当剂量测量涉及到知道实际指数时,需要使用rit进行一些计算以获得它,比如 index = v.size() - 1 - (rit - v.rbegin)

    如果仍然需要索引,那么我坚信最好使用该索引进行迭代

    for(int i = v.size() - 1; i >= 0; --i)
    {
        //do something with v[i] and i; 
    }
    

    这发出了一个警告 i 签名并 v.size() 未签名。 更改为

    for(unsigned i = v.size() - 1; i >= 0; --i) 只是功能上的错误,因为这本质上是一个无止境的循环 :)

    做我想做的事有什么美学上的好方法

    • 没有警告
    • 不包括石膏
    • 不是太冗长

    我希望我不是在寻找不存在的东西:

    9 回复  |  直到 11 年前
        1
  •  56
  •   Rob Kennedy    14 年前

    正如你所指出的,一个 i >= 0 当它是无符号的是,条件总是真的。而不是在初始化时减去1 i 每次迭代后,检查循环条件后再减去1:

    for (unsigned i = v.size(); i-- > 0; )
    

    我喜欢这种风格有几个原因:

    • 尽管 将环绕到 UINT_MAX 在循环的最后,它没有 依靠 在这种行为上——如果类型被签名的话,它的工作原理是一样的。对我来说,依赖于未签名的wrapround感觉有点像一个黑客。
    • 它叫 size() 就一次。
    • 它没用 >= . 每当我看到那个接线员 for 循环,我必须重新阅读它,以确保没有一个由一个错误关闭。
    • 如果更改条件中的间距,可以使用 "goes to" operator .
        2
  •  16
  •   Steve Townsend    14 年前

    没有什么可以阻止你 reverse_iterator 循环还使用多个其他答案中描述的索引。这样,您就可以根据需要在 // do the work 一部分,只需最少的额外费用。

    size_t index = v.size() - 1;
    for(std::vector<SomeT>::reverse_iterator rit = v.rbegin(); 
        rit != v.rend(); ++rit, --index)
    {
      // do the work
    }
    

    尽管我很想知道你需要索引做什么。访问 v[index] 与访问相同 *rit .

        3
  •  5
  •   Nim    14 年前

    为了讨人喜欢!;)

    for(unsigned i = v.size() - 1; v.size() > i; --i)
    
        4
  •  2
  •   Yippie-Ki-Yay    14 年前

    我更喜欢使用反向迭代器变量,因为它仍然易于解释,并允许避免与索引相关的错误。

    有时你可以简单地使用 BOOST_REVERSE_FOREACH ,这将使代码看起来如下所示:

    reverse_foreach (int value, vector) {
       do_something_with_the_value;
    }
    

    实际上,你可以用 foreach 这类循环的语句,但是它们变得有点不明显:

    size_t i = 0;
    
    foreach (int value, vector) {
       do_something;
       ++i;
    }
    
        5
  •  0
  •   Jean-Bernard Jansen    14 年前

    尝试一段时间:

    std::vector<Type> v;
    // Some code 
    if(v.size() > 0)
    {
        unsigned int i = v.size() - 1;
        do
        {
            // Your stuff
        }
        while(i-- > 0);
    }
    
        6
  •  0
  •   Sanja Melnichuk    14 年前

    嗨,我认为使用迭代器的更好方法,就像您在第一个示例中使用的那样,如果您需要获得迭代器索引,可以使用 如果我理解你的问题,计算距离

        7
  •  0
  •   smerlin    14 年前

    回路条件 i != std::numeric_limits<unsigned>::max() ... 或使用 UINT_MAX 如果你觉得太冗长。 或者另一种方式:
    for(unsigned j=0, end=v.size(), i=end-1; j<end; --i, ++j)

    for(unsigned end=v.size(), i=end-1; (end-i)<end; --i)

        8
  •  -3
  •   Kylo    14 年前

    我认为:

    for(unsigned i = v.size() - 1; i >= 0; --i)
    

    如果你查一下就可以了

    !v.empty()
    

    早期的。

        9
  •  -3
  •   Peter Arandorenko    13 年前
    for (it = v.end()-1; it != v.begin()-1; --it)
    {
    }
    

    这个 "goes to" operator 我的头肯定有问题。