Java 仅使用递归将数字从1设置为所选数字

Java 仅使用递归将数字从1设置为所选数字,java,recursion,Java,Recursion,连续7个小时后,我真的需要一些帮助,我需要从递归返回数量的选项,可以通过将数字从1设置为所选数字(最大数字),禁止使用循环/数组,只有递归,数字都是正的(大于0),并且只会更积极,示例:好的:{1,2},坏的:{2,1} 例如: n = 3 , max = 2 n:应该在这一行的数字 ,max:行中可以包含的最大数目 {1,1,1} {1,1,2} {1,2,2} {2,2,2} 从该示例中,应该返回4,因为有4个选项,其中3个数字的值最大为2 另一个: n=2 max=3 {1,1}

连续7个小时后,我真的需要一些帮助,我需要从递归返回数量的选项,可以通过将数字从1设置为所选数字(最大数字),禁止使用循环/数组,只有递归,数字都是正的(大于0),并且只会更积极,示例:好的:{1,2},坏的:{2,1}

例如:

n = 3 , max = 2 
n:应该在这一行的数字 ,max:行中可以包含的最大数目

{1,1,1}
{1,1,2}
{1,2,2}
{2,2,2}
从该示例中,应该返回4,因为有4个选项,其中3个数字的值最大为2

另一个:

n=2
max=3

{1,1}
{1,2}
{1,3}
{2,2}
{2,3}
{3,3}

从这个例子中,它应该返回6,因为有6个选项。

由于时间的关系,我已经编写了一些效率较低的代码,试着看看这个,它会给你dir,我希望

package com.exercise;

import java.util.Arrays;

public class Permutation {

public static void permutation(String str) {
    permutation("", str);
}

private static void permutation(String prefix, String str) {
    int n = str.length();
    if (n == 0)
        System.out.println(prefix);
    else {
        for (int i = 0; i < n; i++)
            permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i + 1, n));
    }
}

private static void permutationOnInt(String prefix, String str, int max) {

    int n = str.length();

    if (n == 0)
        System.out.println(prefix);
    else {
        for (int i = 0; i <= n; i++)
            permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i + 1, n));
    }
}

public static int[] return_Array(int length) {
    int[] a = new int[length];
    for (int i = 0; i < length; i++) {
        a[i] = i + 1;
    }
    return a;

}

public static void main(String[] args) {
    String fn = Arrays.toString(return_Array(3));
    String apple = String.join(",", fn.replace("[", "").replace("]", "").replace(",", "").replaceAll("\\s+", ""));
    permutationOnInt("", apple, 3);
}
}
package.com.exercise;
导入java.util.array;
公共类置换{
公共静态空置换(字符串str){
排列(“,str);
}
私有静态无效置换(字符串前缀、字符串str){
int n=str.length();
如果(n==0)
System.out.println(前缀);
否则{
对于(int i=0;ifor(int i=0;i递归一开始可能很难理解,但一旦你了解了它,就很容易理解。缺点是递归需要比基本for循环更多的空间()。对于某些问题,可以更容易地先编写递归版本,然后再将其作为For循环来编写。此外,如果空间不是问题,则有助于使代码干净(对于循环,则不需要!)

我做了一些基本的递归,至少为你写下的两个例子给出了正确的答案。可能我错过了一个边缘案例:可能是编写每个函数调用和一些(尖锐的)测试用例的一个很好的练习

public int recursiveWrapper(int n, int max) {
    return recursive(n, max, 1, 1);
}

public int recursive(int n, int max, int lower, int current) {
//        // for your convenience
//        System.out.println("n:" + n + " max:" + max + " lowerbound:" + lower + " current:" + current);

    // Base case
    if (n <= 1 && lower == max) {
        return 1;
    }

    // Recursive step
    // Sequence complete, move to next column
    if (current == max) {
        // Make sure the lower bound does not go beyond the max. number
        int updatedLower = (lower + 1 > max) ?  lower : lower + 1;

        return 1 + recursive(n - 1, max, updatedLower, updatedLower);
    }

    return 1 + recursive(n, max, lower, current + 1);
}
注意由于从左到右的数字必须相等或更大的规则而出现的数字模式: 第二列:1>2>3>2>3>3 第一列:1>1>1>2>2>3

递归中的“下限”参数基本上是新“序列”可以采用的最低可能数(其中每个序列都是
下限->最大数
)。基本情况是,下界等于上界,并且每列都完成了所有“序列”。可能不是很清楚的解释-当您看到我复制粘贴的代码中注释行打印出的内容时,可能会有所帮助


注意:也许可以用较少的参数进行递归。请确保阅读大量有关递归的内容(例如,或您的studybook?).递归可以更容易地找到解决方案,并理解复杂和抽象的问题。

如果没有先验知识,这可能是一个挑战性的问题,即使是对一个有经验的数学家来说也是如此。它是组合数学的基本组成部分之一。我将解释我对递归概念的理解维基百科中的快乐

通常
k
用于多集基数(您的问题称之为
n
),而
n
用作可供选择的集合(而非多集)的基数(问题中的
max

对于
f(n,k)
,基本情况是:

f(n, 0) = 1
one way to fill the empty multiset
以及

对于正则情况,我们考虑<代码> n< /代码>元素(从一组选择中)。我们希望计算包含它的所有组合以及缺少它的所有组合。计算不含

n
th元素的所有组合很容易:我们将相同的多集计数函数应用于
k
,只需少一个选择:

f(n - 1, k)
现在,为了计算至少包含一个
n
th元素的组合,我们设想从
n
项中选择所有方式(其中一些项不包含
n
th元素),但在每个组合中保存一个位置,我们将在其中放置
n
th元素,因此我们最终得到:

f(n, k - 1)
总而言之:

函数f(n,k){
如果(n==0)
返回0;
如果(k==0)
返回1;
返回f(n-1,k)+f(n,k-1);
}
console.log(f(2,3));

控制台日志(f(3,2))
连续7个小时后,你写了什么?@NicholasK我用数组写了几个小时,然后注意到它是禁止的,现在我完全搞不清楚,甚至不知道如何开始。对我来说,听起来像是排列操作。好吧,这将有助于增加你的尝试,帮助会更容易。到目前为止,我还不知道如何开始他的太宽了。可能是
f(n - 1, k)
f(n, k - 1)