【问题标题】:increment a for loop by 1 then by 2将 for 循环增加 1,然后增加 2
【发布时间】:2014-10-27 10:40:27
【问题描述】:

我需要在这个循环中将 for 循环递增 1,然后递增 2,然后递增 1。我有一种方法可以做到,但我不喜欢它。有没有人有比这“更好”的实现:

int value= 2;
int changeValue=1;
for(int i=0;i<m;i+=value){
  value+=(changeValue*-1);
 }

语言是 c++

【问题讨论】:

    标签: c++ for-loop increment


    【解决方案1】:

    这个问题有一个公认的答案,但没有人提到这一点,所以我想我会添加一个额外的答案:

    通过选择 2-1-2-1-2-1-2-1 步骤获得的索引如下:

    0,   2, 3,   5, 6,   8, 9, ...
    

    您可以很容易地看到,从 1 开始,每三个索引都丢失了。编写此代码的最简单方法(“最简单”=“以后对开发人员最清晰易读”)是:

    for(int i = 0; i < m; ++i){
        if(i % 3 == 1)
            continue;
        // handle rest of loop
    }
    

    这里没有额外的 step 变量,虽然您也对跳过的索引进行迭代,但迭代不会影响性能,除非您正在查看性能关键代码。

    【讨论】:

    • 简单有效。遍历所有但不对这些采取行动:...保持循环简单,并且保护子句是一种常见的设计模式。我希望即使使用性能关键代码、优化和分支预测(2 on 1 off 很简单,可以涵盖)也不会有任何性能问题。
    【解决方案2】:

    试试这个:

    for (int i = 0, j = 0; i < m; i += (j++ % 2) + 1) {
        //...
    }
    

    循环体中没有任何操作。

    【讨论】:

      【解决方案3】:

      我会这样说清楚

        int i = 0;
        bool twice = false;
      
        while (i < m) {
      
          // code here                                                                
      
          if (!twice) {
            twice = true;
            i++;
          } else {
            twice = false;
            i += 2;
          }
        }
      

      【讨论】:

        【解决方案4】:

        在我看来,一个非常简单的解决方案是展开循环:

        int value= 2;
        int changeValue=1;
        for(int i=0;i<m;i+=value){
            foo(i);
            value+=(changeValue*-1);
        }
        

        变成:

        foo(0);
        for(int i=1;i<m;i+=3){
            foo(i);
            foo(i+2)
        }
        

        这样,您不会增加额外的计算开销来计算循环索引的增量

        【讨论】:

          【解决方案5】:

          我想你可以像这样让它更整洁一点:

          int j = 0;
          for(int i = 0; i < m; i += j++ % 2 == 0 ? 2 : 1 ) {
              //
          }
          

          当然它不是最可读的,它需要一些评论,但它很短

          【讨论】:

            猜你喜欢
            • 2018-02-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-10-20
            • 1970-01-01
            • 2015-04-15
            • 2019-08-28
            • 2011-06-02
            相关资源
            最近更新 更多