2

给定位数,我有此代码可以打印所有“有序”位数的数字

(如果数字是xyz,那么它是有序的,当且仅当 x<y<z),

该代码有效,但我无法理解 for 循环中使用的逻辑。这是递归,但如果有人能解释更多,那就太好了。

class OrderedNumbers{

    public static void main(String args[]){
        printOrdered(0,0,3); // 3 digit numbers
    }

    private static void printOrdered(int number, int prev, int n) {

        if(n==0){
            System.out.println(number);
            return;
        }

        for(int i=(prev+1); i<(11-n); i++){
            printOrdered(number*10 + i, i, n-1) ;
        }

    }

}
4

3 回答 3

3

看看论据。

  • number是迄今为止组成的数字。在添加最后一个数字之前,我们将其乘以 10,以便在该数字上再添加一个数字。
  • prev是前一个数字的值。循环将在此for之后开始一个,从而确保数字中的数字是有序的。
  • n是尚未附加的位数。当它达到零时,已经达到最大递归深度并打印数字。我们还使用循环n中的上限计算。for最后一位不得大于 9,倒数第二位不得大于 8,以此类推。n=1您可以从条件读取的事实中看到这一点i<10,即i<=9

递归调用将传递前一个数字加上一个数字,该数字的值以确保后面的数字更大,并且剩余数字的数量减少一个。

于 2012-10-12T20:30:55.227 回答
1

函数的最后一个参数控制函数调用自身的次数。当printOrdered在循环中调用自身时,它获取当前数字并移动将其乘以十(将数字向左移动一位)。然后它添加i(把它放在那些地方)。当n=0函数知道所有必要的数字都已添加时,它会返回(打印)当前数字。

i从比前一个数字多一个(否则它不会是有序数字)到11-n,这就是说在有数字的n数字中,最高有效数字只能与 一样大11-n。考虑具有 3 位数字的最大有序数789。百位永远不能大于 7,你明白为什么吗?

总之

  • number是当前(可能不完整)的有序数
  • prev是添加到的最后一个数字number
  • n是需要添加的位数number
  • i循环遍历所有可以添加到number下一个位置的数字。它必须大于最后一个数字,但仍为剩余的数字留出空间,这些数字将在再次printOrdered调用时添加。
于 2012-10-12T20:42:57.500 回答
1

首先,请注意,对于要“排序”的数字,最左边的数字必须小于(11-n),其中n是位数。如果您使用 3 位数字,则订购“789”,但如果最左边的数字是 8,然后是 9,则将没有更高的数字来填充最右边的位置。(所有其他数字也是如此。)

在对 的第一次调用中printOrderedfor循环生成所有可以在最左边位置使用的有效数字。对于每个这样的数字,递归调用会生成所有可用于倒数第二位的有效数字,依此类推。number是一个累加器,用于累积要打印的数字,而n倒计时直到要打印的数字已完全累积。prev被误导;它将出现在这个数字的左侧。对于要“排序”的数字,您只能生成高于的数字prev,这就是循环变量初始化为 的原因prev + 1

于 2012-10-12T20:48:08.350 回答