对于具有可变步长的循环 - C ++

时间:2017-08-29 12:09:05

标签: c++ for-loop

我想使用具有可变步长的for循环,特别是我希望i循环中的for变量等于:

  1. 除了可以除以3之外的所有数字,所以:
  2.   

    i = 1-2-4-5-7-8-10-11-13-14-16-17 ...

    1. 除了32之外的所有数字,所以:
    2.   

      i = 1-5-7-11-13-17 ...

      基本代码:

      #include <iostream>
      
      int main()
      {
          int N = 100;
          for ( int i=0; i<N; i++) { //<-----
              //instructions
          }
          return 0;
      }
      

      是否可以使用for循环?

7 个答案:

答案 0 :(得分:3)

for(int i = 0; i < N; i++)
{
    if(i % 3 == 0) // if(i % 3 == 0 || i % 2 == 0) // if(is_skippable(i))
        continue;
    //instructions
}

答案 1 :(得分:1)

使用if条件语句和 continue

for (int i = 0; i < N; i ++)
{
    if (i % 3 == 0)
        continue;
    do_stuff();
}

continue语句会跳过当前循环的其余部分并立即转到下一个循环,因此应该适合您。在上面的示例中,如果变量i除以3,则continue将跳过其后的所有内容,并且do_stuff将不会被执行。

您可以在一个循环中使用多个continue,其中任何一个都将跳过当前循环:

for (int i = 0; i < N; i ++)
{
    if (i % 3 == 0)
        continue;
    if (i % 2 == 0)
        continue; // Another continue
    do_stuff();
}

好吧,让它变得简单:

for (int i = 0; i < N; i ++)
{
    if (i % 3 == 0 || i % 2 == 0)
        continue;
    do_stuff();
}

答案 2 :(得分:0)

i++语句中省略for,并根据循环内“不能被3整除”的算法递增计数器。 ...或者如果逻辑足够简单,请用增量算法替换i++

答案 3 :(得分:0)

您可以尝试使用三元运算符。这使得代码的可读性更加困难(我的意见,但有些人喜欢它),但是你把所有内容放在for语句中。

对于可以除以3的数字,例如:

for (int i = 1; i < N; i = (((i+1)%3 == 0) ? i+2 : i+1)) {
    //Instructions
}

而且,对于可以除以3和2的数字,你可以试试这个:

for (int i = 1; 
 i < N; 
 i = (i+1)%3 == 0 || ((i+1)%2) == 0 ? 
     ((i+2)%3 == 0 || i%2 == 0 ? 
        (i%3 == 0 || (i+1)%2 == 0 ? i+4 : i+3) : i+2 ) : i+1) {
    //Instructions
}

有关三元运算符的更多信息,请单击here

编辑从评论中添加@ AMA的建议(比我的简单)

for (int i = 1; 
     i < N; 
     i = (i+1)%2 == 0 
         ? (i+2)%3 == 0
             ? i+4
             : i+2
         : (i+1)%3 == 0 
             ? i+2
             : i+1) {
    //Instructions
}

答案 4 :(得分:0)

for循环中第三项的作业是为循环控制变量提供下一个值。它最常见的形式只是一个增量:++i,但它可能更复杂。您可以编写其他一些答案中的各种表达式,但它们很难阅读,并且一如既往,难以阅读的代码通常意味着您需要编写函数:

for (int i = 0; i < N; i = next(i))

其中next(i)已定义为如下所示:

int next(int i) {
    ++i;
    if (i % 3 == 0)
        ++i;
    return i;
}

答案 5 :(得分:0)

更新:在评论中建议tobi303Michaël Roy此方法不具有CPU安全性/高效性并且成本高昂。因此,您可能希望查看其他替代方案,除非您正在寻找可读性。

因为,你特别提到改变步骤......

对于第一部分,我会尝试这样的事情:

<强> 1。跳过可被3整除的数字

 for (int i = 1; i < N; i = i + 1 + ((i + 1) % 3 == 0)) {   
    //instructions
 }

<强> 2。跳过可被2 3 整理的数字(&#39;或&#39; ,因为这是您的示例所描述的):

for (int i = 1; i < N; i = i + 2 + 2 * ((i + 2) % 3 == 0)) {
    //instructions
}

工作示例。 Ideone

注意:请注意&#39; i&#39;的初始值。它不是0。

PS :在你的第一个例子中,15不应该在那里。

答案 6 :(得分:0)

对于更现代的c ++样式,您还可以使用lambda来定义高级功能。这不是绝对必要的(下面的advance3advance23可能只是常规函数)但它有助于将您的意图显示在您使用advance函数的位置附近。

请注意,以下内容包括00%n == 0。如果您要排除0,只需从1开始循环。

#include <iostream>

using namespace std;

int main()
{
    int N = 100;

    auto advance3 = []( int &i ){ i++; while( i % 3 == 0 ) { i++;} };

    for ( int i=0; i<N; advance3( i ) ){ 
        cout << i << ", ";
    }
    cout << '\n';


    auto advance23 = []( int &i ){ i++; while( ( i % 3 == 0 ) || ( i % 2 == 0 ) ) { i++;}  };

    for ( int i=0; i<N; advance23( i ) ){ 
        cout << i << ", ";
    }
    cout << '\n';

    return 0;    
}