Java 如何递归地使n个嵌套for循环?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19406290/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 16:54:05  来源:igfitidea点击:

How to make n nested for loops recursively?

javarecursion

提问by Rumpelstiltskin

I have a method that must do the following:

我有一个方法必须执行以下操作:

for (int a01 = 1; a01 <= 25; a01++) {
    for (int a02 = a01 + 1; a02 <= 25; a02++) {
        for (int a03 = a02 + 1; a03 <= 25; a03++) {
            ...
            System.out.println(a01 + "," + a02 + "," + ... + "," + a015);
        }
    }
}

I'd like to specify the number of nested for's (in the case above, I want 15 nested for's). Is there a way to use recursive programming here?

我想指定嵌套 for 的数量(在上述情况下,我想要 15 个嵌套 for)。有没有办法在这里使用递归编程?

采纳答案by Christian Fries

Yes. This can be performed by recursive programming.

是的。这可以通过递归编程来执行。

I assume you do not like to WRITE DOWN these nested for's in source code - as in your example, because this is really ugly programming - like the commentors explain.

我假设您不喜欢在源代码中写下这些嵌套的 for - 就像在您的示例中一样,因为这真的是丑陋的编程 - 就像评论员解释的那样。

The following (pseudo Java-like) code illustrates it. I assume a fixed depth for the nesting. Then you actually like to loop over an integer vector of dimension depth.

以下(伪 Java 类)代码对其进行了说明。我假设嵌套的深度是固定的。然后你实际上喜欢循环一个维度深度的整数向量。

int[] length = new int[depth];
int[] counters = new int[depth];

The array countershas to be initialised to 0 (Arrays.fill(counters,0)). The array lengthhas to be initialised to the number of iterations for the respective for loop.

数组counters必须初始化为 0 ( Arrays.fill(counters,0))。该数组length必须初始化为相应 for 循环的迭代次数。

I assume that you like to perform a certain operation within the inner loop. I will call this performOperation(int[] counters);- it depends on the multi-dimensional counter, i.e. the counters of the outer for's.

我假设您喜欢在内部循环中执行某个操作。我将称之为 performOperation(int[] counters);- 它取决于多维计数器,即外部 for 的计数器。

Then you can run the nested for loops by calling

然后您可以通过调用运行嵌套的 for 循环

nestedLoopOperation(counters, length, 0);

where

在哪里

void nestedLoopOperation(int[] counters, int[] length, int level) {
    if(level == counters.length) performOperation(counters);
    else {
        for (counters[level] = 0; counters[level] < length[level]; counters[level]++) {
            nestedLoopOperation(counters, length, level + 1);
        }
    }
}

In your case your System.out.println() would be

在您的情况下,您的 System.out.println() 将是

performOperation(int[] counters) {
    String counterAsString = "";
    for (int level = 0; level < counters.length; level++) {
        counterAsString = counterAsString + counters[level];
        if (level < counters.length - 1) counterAsString = counterAsString + ",";
   }
   System.out.println(counterAsString);
}

回答by Simon Vega-

I created this program to show all the different possible combination of cards (non repeating). It uses recursive for loops. Maybe it can help you.

我创建了这个程序来显示所有不同的可能的卡片组合(非重复)。它使用递归 for 循环。也许它可以帮助你。

//I'm lazy, so yeah, I made this import...
import static java.lang.System.out;

class ListCombinations {

    //Array containing the values of the cards
    static Symbol[] cardValues = Symbol.values();

    //Array to represent the positions of the cards,
    //they will hold different card values as the program executes
    static Symbol[] positions = new Symbol[cardValues.length];

    //A simple counter to show the number of combinations
    static int counter = 1;

    /*Names of cards to combine, add as many as you want, but be careful, we're
    talking about factorials here, so 4 cards = 24 different combinations (4! = 24),
    but 8 cards = 40320 combinations and 13 cards = 6.23 billion combinations!*/
    enum Symbol {
        AofSpades, TwoofSpades, ThreeofSpades, FourofSpades
    }

    public static void main(String args[]) {

        //I send an argument of 0 because that is the first location which
        //we want to add value to. Every recursive call will then add +1 to the argument.
        combinations(0);
    }

    static void combinations(int locNumber) {

        /* I use a recursive (repeating itself) method, since nesting for loops inside
        * each other looks nasty and also requires one to know how many cards we will
        * combine. I used 4 cards so we could nest 4 for loops one after another, but
        * as I said, that's nasty programming. And if you add more cards, you would
        * need to nest more for loops. Using a recursive method looks better, and gives
        * you the freedom to combine as many cards as you want without changing code. */

        //Recursive for loop nesting to iterate through all possible card combinations
        for(int valueNumber = 0; valueNumber < cardValues.length; valueNumber++) {
            positions[locNumber] = cardValues[valueNumber];
            if (locNumber < (cardValues.length-1)) {
                combinations(locNumber + 1);
            }

            //This if statement grabs and displays card combinations in which no card value
            // is repeated in the current "positions" array. Since in a single deck,
            // there are no repeated cards. It also appends the combination count at the end.
            if (locNumber == (cardValues.length-1) && repeatedCards(positions)) {
                for (int i = 0; i < cardValues.length; i++) {
                out.print(positions[i]);
                out.print(" ");
                }
                out.printf("%s", counter);
                counter++;
                out.println();
            }
        }
    }

    static boolean repeatedCards(Symbol[] cards) {

        /*Method used to check if any cards are repeated in the current "positions" array*/

        boolean booleanValue = true;

        for(int i = 0; i < cardValues.length; i++) {
            for(int j = 0; j < cardValues.length; j++) {
                if(i != j && cards[i] == cards[j]) {
                    booleanValue = false;
                }
            }
        }
        return booleanValue;
    }
}