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

For loop with variable step size - C++

本文关键字:循环 于具      更新时间:2023-10-16

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

  1. 除了可以用3划分的数字以外的所有数字:

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

  1. 除了可以用32划分的数字以外的所有数字。

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循环可以吗?

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

使用 if条件语句和 continue

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

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

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

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();
}

您可以尝试使用三元运算符。它使您的代码的可读性更加困难(我认为,但有些人喜欢它),但是您将所有内容都放在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
}

有关三元操作员的更多信息,请单击此处

编辑添加 @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
}

只需从 for语句中省略 i++,然后根据您的算法在循环中"不排除三个"的算法来增加计数器。...或者如果逻辑很简单,请用增量算法替换i++

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

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

定义了for0的位置以这样的外观:

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

update :tobi303和michaëlRoy在评论中建议这种方法不是CPU firend/firend firendly/fige效率,而且代价高昂。因此,除非您要寻找的可读性,否则您可能想查看其他替代方案。

以来,您特别提到要更改步骤,因此...

在第一部分中,我会尝试这样的事情:

1。跳过数字可除以3

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

2。跳过数字可除以2 3 '或',因为这是您的示例描绘的):

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

工作示例。IDEONE

NOTE :请注意" I"的初始值。它是1不是0。

ps :在您的第一个示例中,15不应该在那里。

对于更现代的C 样式,您也可以使用lambda来定义提前功能。这不是严格必要的(下面的advance3advance23可能只是常规功能),但它有助于向您的意图显示您使用advance函数的位置。

请注意,以下内容包括0,因为0%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;    
}