动态嵌套循环

7

我是一个相对新手的程序员。正如标题所示,我需要一个算法,让我得到一个变量嵌套循环的相同函数。即:

for(..)
{ for(..){
for(..){....}
.
.
}}

嵌套循环的数量将根据用户输入而变化。我想要实现的是找到数字(10、9、8、7、6、5、4)的所有组合。我已经阅读了许多资料,但要么我没有完全理解它们(我是编程新手),要么它们不能满足我的目的。我以后需要这些组合进行某些计算,而不仅仅是打印所有组合。一个方法,我学到的是使用递归。我不完全理解它。我试图制作一个递归函数,但失败了。这就是我想要的。

10 10 10 
10 10 9
10 10 8
.
.
.
4  4  4 

这个数字可能会变化(比如10 10 10 10,10 10 10 9...),这些组合将被存储在一个数组中,以便稍后进行操作。请保持简单并加上注释。

首选语言是Java,但任何语言都可以。强烈建议提供通用算法。附注:这不是一项作业。

感谢Amit。以下是可行的代码:

def findcombinations(array,n,sol,tt=[]):
    if (n== 0):
        tt.append(sol[:])
        return
    for x in array:
        sol.append(x)
        findcombinations(array,n-1,sol,tt)        
        del sol[-1]
    return tt      

调用该函数使用 print(findcombinations([1,2],3,[]))


严谨地说,“10”不是一个数字。您可能希望重新措辞。 - Aaron Dufour
抱歉..我会将其更改为数字..谢谢 - Oasa
3个回答

5
通常当您需要“动态循环”时,这是您实际上需要递归的强烈指示。
例如,在数组[pseudo code]中查找大小为n的数字的所有可能组合:
findCombinations(array,n,sol):
   if (sol.size == n): //stop condition for the recursion
      print sol
      return
   for each x in array:
      sol.append(x)
      findCombinations(array,n-1,sol) //recursive call
      sol.removeLast() //cleaning up environment

上述伪代码将查找并打印由array中的元素组成的长度为n的所有序列[每个元素可以出现多次]。

实际上这里的“sol”是什么? :( 对不起,我太菜了。 - Oasa
我确定我错过了很多。请解释一下。我错了。你能具体说明一下吗?我以为我可以从一个普遍的表述中理解,但我错了。谢谢。 - Oasa
1
@Oasa:不需要道歉。sol保存当前排列[您正在处理的]。当算法开始时,它被初始化为空列表,并在运行时添加元素。有许多实现此sol的方法,但最简单的方法可能是使用ArrayList。请注意,ArrayList.add(element)将元素附加到列表末尾。 - amit
实际的代码怎么样?伪代码似乎可以工作。但是如果我们只有普通的数组,而没有像append()和removeLast()这样的其他数据结构方法呢?请发布一个实际的工作代码。这真的会很有帮助! - santahopar
@armanali 我知道已经晚了。我会将可工作的代码发布为编辑。 - Oasa
显示剩余9条评论

3

所以你有一个或多个(好吧,也许是三个或更多)数字,应该能够在4到10之间变化?一种方法是使用一个简单的计数器和一个将计数器转换为数字数组的函数。

伪代码如下:

counter_to_array(counter, positions):
  var array = new array(positions)

  for 0 <= i < positions:
    n = counter % 7
    counter = counter // 7  # INTEGER DIVISION
    array[i] = 4 + n

  return array

换句话说,您的数组是由计数器隐含的,您可以根据需要重新创建它。这可能不是您实际需要的,如所述,数组将变为“4 4 4”“5 4 4”“6 4 4”...“10 10 9”“10 10 10”,但更改该顺序就像更改填充数组位置的顺序一样简单。
工作示例: 我们想生成一个4元素计数器,第11个。
  1. 我们创建一个名为array的4元素数组。
  2. 我们循环遍历数组位置:
  3. 我们将array [0]设置为8(4 +(11 mod 7))
  4. 我们将计数器设置为1(11 div 7)
  5. 我们将array [1]设置为5(4 +(1 mod 7))
  6. 我们将计数器设置为0(1 div 7)
  7. 我们将array [2]设置为4
  8. 我们将array [3]设置为4
因此,第11个数组将是[8 5 4 4]

假设我调用counter_to_array(10,4)它会创建一个新的变量数组,维度为4; 那么这个数组是array[4]吗?然后是一个循环,从0到4。 然后n = 3; 计数器= 3; 数组[0]=3; 数组[1]=3; 等等。那么我得到了一个全是3的数组?我确定我错过了很多。请解释一下。我错了。您能具体说明吗?我以为我可以从一般表示中理解。但我错了。我不明白%7的目的:(谢谢。 - Oasa
@oasa 计数器每轮都会除以7,我添加了一个实例,希望能帮到你。 - Vatine
我真的无法理解。可能是因为我太菜了。没关系。我从@amit的答案中找到了它。无论如何,谢谢你。一直受人赞赏。 - Oasa

2
下面给出了使用while循环的解决方案。代码使用C++编写,需要在包含和定义语句中使用#。
include <iostream>
define MAXROWS 9
define MAXVALUES 9

using namespace std;
char display[] = {'1','2','3','4','5','6','7','8','9'};

int main() {

int arrs[MAXROWS];  // represent the different variables in the for loops

bool status = false;

for (int r=0;r<MAXROWS;r++)
    arrs[r] = 0;  // Initialize values

while (!status) { 

    int total = 0;
    // calculate total for exit condition
    for (int r=0;r<MAXROWS;r++)
        total +=arrs[r];
    // test for exit condition
    if (total == (MAXVALUES-1)*MAXROWS)
        status = true;

    // printing
    for (int r=0;r<MAXROWS;r++)
        cout << display[arrs[r]]; // print(arrs[r])
    cout << endl;  // print(endline)

    // increment loop variables
        bool change = true;
    int r = MAXROWS-1;  // start from innermost loop
    while (change && r>=0) {
        // increment the innermost variable and check if spill overs
        if (++arrs[r] > MAXVALUES-1) {        
            arrs[r] = 0;  // reintialize loop variable
            // Change the upper variable by one
            // We need to increment the immediate upper level loop by one
            change = true;
        }
        else
            change = false; // Stop as there the upper levels of the loop are unaffected

        // We can perform any inner loop calculation here arrs[r]

        r=r-1;  // move to upper level of the loop

    }

}

[链接]http://www.codeproject.com/Tips/759707/Generating-dynamically-nested-loops 它展示了如何将一个简单的多重嵌套循环转换为动态循环,而不使用递归。


你不应该发布仅包含链接的答案。 - Nuno Furtado
1
抱歉,我已经包含了一个描述可能解决方案的示例代码。 - natkit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接