Java 具有头部和尾部的嵌套循环的数量可变

Java 具有头部和尾部的嵌套循环的数量可变,java,recursion,Java,Recursion,我有这些嵌套for循环: void fun() { int n = 5; int c = 0; for (int i = 0; i < n; i++) { head_function(i, c); for (int j = 0; j < n; j++) { head_function(j, c); for (int w = 0; w < n; w++) {

我有这些嵌套for循环:

void fun() {

    int n = 5;
    int c = 0;

    for (int i = 0; i < n; i++) {
        head_function(i, c);
        for (int j = 0; j < n; j++) {
            head_function(j, c);
            for (int w = 0; w < n; w++) {
                head_function(w, c);
                for (int x = 0; x < n; x++) {
                    head_function(x, c);

                    c++;
                    body(c);

                    tail_function(x, c);
                }
                tail_function(w, c);
            }
            tail_function(j, c);
        }
        tail_function(i, c);
    }
}
private int c;

void loopAtDepth(int depth){
    if( depth == 0){
       c++;
       body(c);
    } else {
        for(int i = 0; i < n; i++){
            head_function(i, c);
            loopAtDepth(depth - 1)
            tail_function(i, c);
        }
    }
}
void fun(){
int n=5;
int c=0;
对于(int i=0;i
头函数和尾函数做什么并不重要,只要它们能够跟踪它们的指数i,j,w,x

我想要的是有任意数量的嵌套for循环,而不是只有四个


我在这里找到的其他解决方案并不适合我,因为我想它们不包括head和tail函数。

因为n似乎总是相同的,所以您可以尝试(c现在是私有字段,n是嵌套for循环的数量):

privateintc;
void loopAtDepth(int depth){
如果(深度==0){
C++;
机构(c);
}否则{
对于(int i=0;i
以下是一个框架,让您开始学习。您可以根据需要随意添加参数和更改签名

public void doStuffRecursively(int nTimes){
    doIt(nTimes);
}

void doIt(int depth){
    if(depth==0)
        body();
    else{
        head(depth);
        doIt(depth-1);
        tail(depth);
    }
}

void body(){}

void head(int depth){}
void tail(int depth){}

这是一个非递归版本,它迭代循环索引的单个数组

您的代码有点小麻烦:最里面的循环与其他循环不同,它只调用
body()
并递增常规计数器。我通过检查我的循环内部的“内部循环”来解释这一点,该“内部循环”由
loop
变量0表示

我还将您的
n
从5更改为3(
max
),只是为了减小输出的大小。我认为代码的其余部分非常简单

public class Test {

    public static void main(String[] args) {
        System.out.println("\n Loop 1\n");
        loop( 1 );
        System.out.println("\n Loop 2\n");
        loop( 2 );
        System.out.println("\n Loop 3\n");
        loop( 3 );
    }

    public static void loop( int depth ) {
        int[] indices = new int[depth];
        final int max = 3;
        int count = 0;
        for( int x = 0; x < depth - 1; x++ )
            head( x, count );
        outer:
        for(;;) {
            for( int loop = 0; loop < indices.length; loop++ ) {
                if( indices[loop] < max ) {
                    head( indices[loop], count );
                    if( loop == 0 ) {
                        count++;
                        body( indices[loop], count );
                    }
                    tail( indices[loop], count );
                    indices[loop]++;
                    break;
                } else {
                    if( loop == indices.length - 1 ) break outer;
                    indices[loop] = 0;
                }
            }
        }
    }

    private static void head( int index, int counter ) {
        System.out.printf( "head index=%d count=%d%n", index, counter );
    }
    private static void body( int index, int counter ) {
        System.out.printf( "body index=%d count=%d%n", index, counter );
    }
    private static void tail( int index, int counter ) {
        System.out.printf( "tail index=%d count=%d%n", index, counter );
    }

}

使用递归方法和递归深度作为参数。建议不要使用递归,因为大多数硬件都专门处理堆栈内存,不需要的递归往往比其他方法使用更多的堆栈内存。可以使用单个循环和数组来保持任意数量的索引。编码要复杂得多,但如果“深度”很大,最好是这样编码。@markspace现在对您来说,这是过早的优化。一个人应该写清楚简洁的代码,递归在这里是很自然的,如果OP是4深的,他可以在它成为问题之前将它加倍多次。你甚至可以通过增加虚拟机堆栈内存来延长修复时间;递归应该几乎总是转换成循环。虚拟机内存与此无关;CPU中的堆栈内存会很快溢出。如果OP堆栈的深度从未超过4或5,请确保它们没有问题。但是,这种问题通常会迅速发展,这并不局限于CPU。对于java,只需传递
-Xss
,VM中的堆栈内存就会增加。Java堆栈与Java应用程序堆栈不同,所以我想它是一个完全不同的堆分配区域。对于gcc,编译时传递
--stack
。堆栈是指向指定内存大小末尾的寄存器。堆栈溢出是指由于低于指定区域允许的最低索引而导致MMU错误。
 Loop 1

head index=0 count=0
body index=0 count=1
tail index=0 count=1
head index=1 count=1
body index=1 count=2
tail index=1 count=2
head index=2 count=2
body index=2 count=3
tail index=2 count=3