【问题标题】:Nested for loops recursion嵌套for循环递归
【发布时间】:2018-01-14 10:52:11
【问题描述】:

我在很多地方查找并试图了解如何通过递归获得任意数量的嵌套 for 循环。但我的理解显然是错误的。

我需要在 n 维空间中以网格模式生成坐标。实际的问题有不同范围的不同坐标,但为了先把更简单的事情做对,我在下面的代码中使用了相同的整数步坐标范围。

#include <iostream>
using namespace std;

void recursion(int n);

int main(){    
  recursion(3);
  return 0;
}



void recursion(int n)
{
  if(n!=0){
    for(int x=1; x<4; x++){
        cout<<x<<" ";
        recursion(n-1);
  }
}
  else cout<<endl;
}  

我想要并且期望输出是:

1 1 1
1 1 2
1 1 3
1 2 1
1 2 2
1 2 3
1 3 1
1 3 2
1 3 3
2 1 1
2 1 2
2 1 3
2 2 1
2 2 2
2 2 3
2 3 1
2 3 2
2 3 3
3 1 1
3 1 2
3 1 3
3 2 1
3 2 2
3 2 3
3 3 1
3 3 2
3 3 3

相反,我得到的输出是

1 1 1 
2 
3 
2 1 
2 
3 
3 1 
2 
3 
2 1 1 
2 
3 
2 1 
2 
3 
3 1 
2 
3 
3 1 1 
2 
3 
2 1 
2 
3 
3 1 
2 
3 

我就是不知道出了什么问题。任何帮助找出错误甚至生成坐标的另一种方式将不胜感激。谢谢!

【问题讨论】:

  • 你不需要递归。回忆一下小学时代的加法。但是如果你坚持递归,你需要将前缀向下传递给每个递归调用,因为你想在每一行上重复前缀;你不能像现在这样在顶部打印一次。
  • 使用您的调试器一步一步地完成它,并观察它的运行情况。你会看到错误,如果不是如何修复它
  • @IgorTandetnik 如果您能详细说明一下,那就太好了。

标签: c++ for-loop recursion coordinates


【解决方案1】:

Non-recursive solution 基于 add-with-carry:

#include <iostream>
using namespace std;

bool addOne(int* indices, int n, int ceiling) {
    for (int i = 0; i < n; ++i) {
        if (++indices[i] <= ceiling) {
            return true;
        }
        indices[i] = 1;
    }
    return false;
}

void printIndices(int* indices, int n) {
    for (int i = n-1; i >= 0; --i) {
        cout << indices[i] << ' ';
    }
    cout << '\n';
}

int main() {
    int indices[3];
    for (int i=0; i < 3; ++i) {
      indices[i] = 1;
    }

    do {
      printIndices(indices, 3);
    } while (addOne(indices, 3, 3));
    return 0;
}

Recursive solution,从您的原始代码中抢救出来:

#include <iostream>
#include <sstream>
#include <string>
using namespace std;

void recursion(int n, const string& prefix);

int main(){    
  recursion(3, "");
  return 0;
}

void recursion(int n, const string& prefix)
{
  if (n!=0) {
    for(int x=1; x<4; x++){
        ostringstream os;
        os << prefix << x << ' ';
        recursion(n-1, os.str());
    }
  }
  else cout << prefix << endl;
}

【讨论】:

  • 非递归的方法真的很棒。非常感谢 :) 另外,这两种方法中哪一种会更快?
  • which of the two methods will be faster?我把这个问题留给读者作为练习。
【解决方案2】:

根据 Igor 的评论,您需要一个增量函数。

让我们使用std::vector 来表示每个维度。也就是说,vector[0] 是第一个维度,vector[1] 是第二个维度,依此类推。

使用向量可以让我们在没有任何硬编码数字的情况下确定维数。 vector.size() 将是维数。

这是一个帮助您入门的函数:

void Increment_Coordinate(std::vector<int>& coordinates,
                          int               max_digit_value,
                          int               min_digit_value)
{
  unsigned int digit_index = 0;
  bool apply_carry = false;
  do
  {
    apply_carry = false;
    coordinates[digit_index]++; // Increment the value in a dimension.
    if (coordinates[digit_index] > max_digit_value)
    {
      // Reset the present dimension value
      coordinates[digit_index] = min_digit_value;
      // Apply carry to next column by moving to the next dimension.
      ++digit_index;
      apply_carry = true;
    }      
  } while (apply_carry);
  return;
}

编辑 1 这只是一个基础。该功能需要进行边界检查。
此函数不支持不同大小的维度。这留给读者或OP练习。

【讨论】:

    猜你喜欢
    • 2018-08-12
    • 1970-01-01
    • 1970-01-01
    • 2014-10-01
    • 2013-09-25
    • 2020-03-09
    • 2014-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多