【问题标题】:Create a recursive for statement in c++在 C++ 中创建递归 for 语句
【发布时间】:2017-02-06 02:44:00
【问题描述】:

我想知道是否真的可以在 C++ 中创建/定义自制的for 语句。这里已经问过类似的问题:

"How to create a for loop like command in C++? #user9282's answer"

我的要求是,我们是否可以制作一个 for,它可以根据我们的需要(n 次)执行尽可能多的 for

例如,这是一个基本的 for 循环语句:

for (int i = 0; i < 10; i++) { ... }

我想知道新的 for 循环是否可以导致更像这样:

int x = 20; // individual loops
int y = 3; // = amount of for-loops performed (in this case, 3)

// maybe some code generating for-loops here or something...

// result:
for (int i = 0; i < x; i++)
{
    for (int j = 0; j < x; j++)
    {
        for (int k = 0; k < x; k++)
        {
            // if "y" was equal to 5, there would be 2 more for-loops here
            instructions; // we can use "i", "j", "k", ... here
        }
    }
}

你认为这在 c++ 中可行吗?

[编辑:使上面的代码更清晰]

一句话:我想创建一个语句(例如 if、while、for、switch)将 for-loops 放入 for-loops(就像上面的代码在 for 循环中使用 for 循环一样),所以我们可以在 相同的范围内访问多个增量(i、j、k、...) /strong>。

【问题讨论】:

  • 完全不清楚循环应该做什么
  • 这会解决什么问题?
  • 没有人想要创建一个三声明。因为得到了所有的爱。
  • 请解释您要做什么;例如是iterating over tuples 还是over multi-dimensional arrays,还是什么?
  • 您的“一句话”也没有任何意义。尝试使用较小的字词?

标签: c++ for-loop recursion assembly statements


【解决方案1】:

您可以使用包含 for 循环的递归函数轻松做到这一点。我会这样做:

void foo() {
    for (...) {
        foo();
    }
}

这样,您可以根据需要执行任意数量的嵌套 for 循环。

但是,如果您想在代码中定义递归嵌套 for 循环而不定义外部函数,则可以使用 lambda:

auto recursive = [](auto func) {
    // This is needed to make a recursive lambda
    return [=](auto... args){
        func(func, args...);
    };
};

auto nestedForLoop = recursive([](auto self){
    // Here's your recursive loop!
    for (...) {
        self();
    }
});

// You can simply call `nestedForLoop` to execute loop
nestedForLoop();

【讨论】:

    【解决方案2】:

    如果您有 n 个嵌套的 for 循环具有相同的绑定 x,那么您正在执行 xn 次迭代。在这种情况下,为了方便起见,您可以只使用单个索引并将其转换为多个索引。对于 n = 2,例如:

    for (int z = 0; z < x * x; ++z) {
      const int i = z / x;
      const int j = z % x;
      // ...
    }
    

    对于 n = 3:

    for (int z = 0; z < x * x * x; ++z) {
      // The last "% x" in this line is for illustration only.
      const int i = (z / x / x) % x;
      const int j = (z / x) % x;
      const int k = z % x;
      // ...
    }
    

    ijk等是当前迭代数z转换为基数x的数字。您可以将其概括为递归函数,或者将数字解压缩为 vector

    【讨论】:

    • 你的回答很好,很容易地解决了我的问题......当你想到它时,它是如此简单!谢谢大佬!
    • 出于性能原因,最好有一个包含特定计数器的 y 元素实例,并增加它们(使用溢出逻辑)而不是单个 z 按 div/modulo 拆分(这也将可能会很快溢出 int,考虑到 x = 16, y = 8 已经溢出 32b int,而将元素 std::array&lt;int, 8&gt; 从 0 增加到 15 仍然可以。
    • 1.7*10^308 是双精度数可以处理的最大值,除了 2^32 用于整数。然后我们可以使用 double 作为计数器而不是使用整数。这样做我们可能会降低性能,但计数器仍然会更大。
    • @Ped7g:是的,增量更新计数器比使用除法重新计算更有效。我想先介绍一下通用公式。
    • @whiteiden97:最好使用 64 位整数。请记住,浮点数的范围更大但精度更低——随着数字变大,可表示的值越来越少,因此您只能表示尾数范围内的整数,[-2^54,+2^54] 为IEEE754 double。这仍然很大,但没有理由涉及浮点。
    【解决方案3】:

    快速回答:

    #include <iostream>
    
    using namespace std;
    
    void recursive(int x, int y, int tempY) // 2d recursive for loop 
    {
        if (x > 0)
        {
            if (y > 0)
            {
                cout << x << " " << y << " \n ";
                recursive(x, y - 1, tempY);
            }
            else
            {
                y = tempY;
                recursive(x - 1, y, tempY);
            }
        }
    }
    
    void recursive(int x, int y, int z, int tempY, int tempZ) // 3d recursive for loop
    {
        if (x > 0)
        {
            if (y > 0)
            {
                if (z > 0)
                {
                    cout << x << " " << y << " " << z << " \n ";
                    recursive(x, y, z - 1, tempY, tempZ);
                }
                else
                {
                    z = tempZ;
                    recursive(x, y - 1, z, tempY, tempZ);
                }
            }
            else
            {
                y = tempY;
                recursive(x - 1, y, z, tempY, tempZ);
            }
        }
    }
    
    int main()
    { 
        recursive(1, 2, 2); // x = 1, y = 2
        recursive(1, 2, 3, 2, 3); // x = 1, y = 2, z = 3
    }
    

    【讨论】:

      【解决方案4】:

      快速回答:

      void n_for_loop(int x, int size, int arr[])
      {
          static int* arrTemp(new int[size]);
          if (x >= size)
          {
              for (int i = 0; i < size; i++)
              {
                  cout << arrTemp[i] << " ";
              }
              cout << endl;
              return;
          }
          for (int i = 0; i < arr[x]; i++)
          {
              arrTemp[x] = i;
              n_for_loop(x + 1, size, arr);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-04-17
        • 1970-01-01
        • 2013-08-25
        • 1970-01-01
        • 2018-11-13
        • 2020-11-22
        • 1970-01-01
        相关资源
        最近更新 更多