ArrayList上的Java递归

ArrayList上的Java递归,java,algorithm,recursion,Java,Algorithm,Recursion,我有一个int数组列表 主程序-调用一个方法以获取列表中所有(n个成员)成员组合的总和。其中n可以是2-6之间的任意值。例如,原始列表为{1,2,3,4,5};那么输出应该是{6,7,8,8,9,10,9,10,11,12},其中n=3 我正在寻找最佳的方法来做到这一点。现在,我编写程序(正在运行)的方式没有递归。我有所有数字的方法,即 MyMethod2 -- gives me all the sum of 2 member combinations of MyArrayList MyMeth

我有一个int数组列表

主程序-调用一个方法以获取列表中所有(n个成员)成员组合的总和。其中n可以是2-6之间的任意值。例如,原始列表为{1,2,3,4,5};那么输出应该是{6,7,8,8,9,10,9,10,11,12},其中n=3

我正在寻找最佳的方法来做到这一点。现在,我编写程序(正在运行)的方式没有递归。我有所有数字的方法,即

MyMethod2 -- gives me all the sum of 2 member combinations of MyArrayList
MyMethod3 -- gives me all the sum of 3 member combinations of MyArrayList
MyMethod4 -- gives me all the sum of 4 member combinations of MyArrayList
......
所以,你可以看到有很多重复的代码集

以及当前编写程序的方式(例如我的方法3):

MyMethod3
ArrayList sum=新的ArrayList();
对于(i=0;i
n=6的MyMethod可能会变得相当长。而且“n”在将来可能会改变

有没有更好的方法来做到这一点,使用递归来最小化重复代码,并使用数字n作为方法调用的变量。Java中是否有一个标准包可以帮助递归


添加基于@Maertin建议的代码-这对我很有用

    ArrayList<Integer> myArray = new ArrayList<Integer>();
    myArray.add(5);
    myArray.add(6);
    myArray.add(4);
    myArray.add(2);
    myArray.add(1);

    ArrayList<Integer>  finalSumArray = combineTwoArrayList(3, myArray, myArray);

public static ArrayList<Integer> combineTwoArrayList(int n, ArrayList<Integer> origArray, ArrayList<Integer> finalSumArray) {

    if (n == 1)  return finalSumArray;

    ArrayList<Integer> finalSumArray = new ArrayList<Integer>();

    for (int i = 0; i < sumArray.size() - 1; i++){
        for (int j = i + 1; j < origArray.size(); j++){

            finalSumArray.add(sumArray.get(i) + origArray.get(j));

        }
    }  

    --n;

    return combineTwoArrayList(n, origArray, finalSumArray);

}
ArrayList myArray=new ArrayList();
添加(5);
myArray.add(6);
myArray.add(4);
myArray.add(2);
myArray.add(1);
ArrayList finalSumArray=CombinetWharray列表(3,myArray,myArray);
公共静态ArrayList CombinetWharray列表(int n,ArrayList origArray,ArrayList finalSumArray){
如果(n==1)返回finalSumArray;
ArrayList finalSumArray=新的ArrayList();
对于(int i=0;i
您可以使用递归。基本上,您应该只有两个for循环。(这是两个成员组合的代码)。计算“总计”时,将每个“总计”值传递给ArrayList MyArrayList 2。现在对于MyMethod3,使用MyArrayList 2和原始ArrayList的元素,再次查找新的“总计”值并将其传递给MyArrayList 3。对于MyMethod4,使用MyArrayList 3和原始ArrayList的元素,再次查找新的“总计”值并将其传递给MyArrayList 4

您希望通过递归实现这一点是正确的,因为现在,对于n个成员组合,您可以使用一个带有参数
n
的方法,而不是使用三个单独的方法

public int nCombinationSum( int n, int i, ArrayList<Integer> arr, ArrayList<Integer> sumArr) {
    /* Gets n-combination sums and puts into sumArr
       Input: n consecutive element combination, current index i in arr, and output ArrayList
       Output: Gets n consecutive element combinations in arr from index i to index (i + n) and puts into sumArr
    */

    //**BASE CASE**

    //if index out of arr bounds 
    if( i + n > arr.size() )
        return 0;

    //**RECURSIVE CASE**

    else { 
        //sum of values in arr from i to (i + n)

        int currComboSum = 0; 
        for( int j = 0; j < n; j++ )
            currComboSum += arr.get(j); 

        //adding sum to next element in resultant array
        sumArr.add( currComboSum );

        return nCombinationSum( n, i + 1, arr, sumArr );
    }
}
public int-nCombinationSum(int-n,int-i,ArrayList-arr,ArrayList-sumArr){
/*获取n个组合和并放入sumArr
输入:n个连续元素组合,arr中的当前索引i,输出ArrayList
输出:从索引i到索引(i+n)获取arr中的n个连续元素组合,并放入sumArr
*/
//**基本情况**
//如果索引超出arr界限
如果(i+n>阵列大小())
返回0;
//**递归案例**
否则{
//从i到(i+n)的arr值之和
int currComboSum=0;
对于(int j=0;j
用法 在main方法中,可以调用nCombinationSum并为其提供组合类型(
n
)、起始索引(在本例中为
0
)和arrayList(
arr
),以及要在其中追加和的arrayList(
sumArr

这还有一个潜在的额外好处,即允许您从某个索引开始添加任何n组合和。如果您愿意,您也可以添加一个结束索引,但这是相当扩展的


编辑:请编辑您的问题,以反映您希望结果是一个总和的数组列表,而不是总和。现在还不清楚

基本上,你想要做的递归,一般来说,是设置一个基本情况和一个递归情况

基本情况是如果索引超出范围,因为您将调用从索引
i
i+n
的所有元素

对于递归情况,使用下面的算法计算
arr
中的每个元素,然后继续返回带有下一个索引值的函数,函数将继续运行,直到超出边界

算法
  • 求n-组合元素之和
  • 将该总和追加到结果数组
    sumArr

  • 请随意参考上面的代码以供参考。

    您可以使用递归。基本上,您应该只有两个for循环。(这是两个成员组合的代码)。当您得到这些总和时,将其传递给数组MyArrayList2。现在对于MyMethod3,使用MyArrayList 2和原始ArrayList的元素,再次查找和并将其传递给MyArrayList 3。对于MyMethod4,使用MyArrayList 3和原始ArrayList的元素,再次查找和并将其传递给MyArrayList 4。对于我的方法5,yada yada yada…谢谢@Pham。那是一个编辑错误。修复了上面的代码。范忠说的问题仍然存在。MyMethod2的for循环限制必须为iYou are correct@Maertin第2条注释。我回到原始代码并进行了检查。相应地更新了上述代码。你的第一个建议看起来也不错。我将举一个例子并回答。很好,既然MyMethod2已经开始工作,在for循环中,当计算total时,将total的值传递给一个新的arraylist。您必须针对Tot递归调用原始ArrayList
    public int nCombinationSum( int n, int i, ArrayList<Integer> arr, ArrayList<Integer> sumArr) {
        /* Gets n-combination sums and puts into sumArr
           Input: n consecutive element combination, current index i in arr, and output ArrayList
           Output: Gets n consecutive element combinations in arr from index i to index (i + n) and puts into sumArr
        */
    
        //**BASE CASE**
    
        //if index out of arr bounds 
        if( i + n > arr.size() )
            return 0;
    
        //**RECURSIVE CASE**
    
        else { 
            //sum of values in arr from i to (i + n)
    
            int currComboSum = 0; 
            for( int j = 0; j < n; j++ )
                currComboSum += arr.get(j); 
    
            //adding sum to next element in resultant array
            sumArr.add( currComboSum );
    
            return nCombinationSum( n, i + 1, arr, sumArr );
        }
    }