【问题标题】:Use recursion for looping使用递归进行循环
【发布时间】:2018-09-03 04:52:26
【问题描述】:

我如何使用递归编写一个 java 程序,计算涉及从 0 到 3 的任何 3 个数字的所有可能组合,并将总和为 5。允许重复。

答案应该像这样打印所有排列

              3 + 2 + 0
              3 + 1 + 1
              3 + 0 + 2
              2 + 2 + 1
              2 + 1 + 2
              2 + 0 + 3
              1 + 3 + 1
              1 + 2 + 2
              1 + 1 + 3

我尝试过编写一个函数,但我认为它效率低下。谁能告诉我如何优化它以获得更好的执行时间并且没有那么多ifs

public class Combinations 
{
    static int aux = 0;
    static int temp;
    static void findCombinations(int sum, int max,int min)
    {
        if(max <= 2)
        {
            if(max <= 0)
            {
                if(aux >= 3)
                {
                    System.out.println("max: "+max);
                    System.out.println("min: "+min);
                    System.out.println("Aux:"+aux);
                    System.out.println("-----------");
                    return;
                }
                else
                {
                    System.out.println("max: "+max);
                    System.out.println("min: "+min);
                    System.out.println("Aux:"+aux);
                    System.out.println("-----------");
                    aux = aux + 1;
                    min = min - 1;
                    findCombinations(sum, max, min);
                }
            }
            else
            {
                System.out.println("max: "+max);
                System.out.println("min: "+min);
                System.out.println("Aux:"+aux);
                System.out.println("-----------");
                aux = aux + 1;
                max = max - 1;
                findCombinations(sum, max, min);
            }
        }
        else
        {
            System.out.println("max: "+max);
            System.out.println("min: "+min);
            System.out.println("Aux:"+aux);
            System.out.println("-----------");
            max = max - 1;
            min = min + 1;      
            findCombinations(sum, max, min);
        }
    }
    //Driver code
    public static void main(String a[])
    {
        int n = 5;
        int max_bound = 3;
        int min_for_sum = n - max_bound; 
        findCombinations(n,max_bound,min_for_sum);
    }
}

代码输出如下

最大:3 分钟:2 辅助:0 +++++++++ 最大:2 分钟:3 辅助:0 +++++++++++++ 最大:1 分钟:3 辅助:1 ++++++++++ 最大值:0 分钟:3 辅助:2 ++++++++++ 最大值:0 分钟:2 辅助:3

【问题讨论】:

  • 您通常会从编写一个类并添加一个main 方法开始。您的具体问题是什么?
  • public static void partition(int n, int max, String p) { if (n == 0) { System.out.println(p);返回; } for (int i = Math.min(max, n); i >= 1; i--) { partition(n-i, i, p+" "+i );我如何编辑分区函数以仅包含 3 个数字。它将递归划分以包括甚至 1+1+1+1+1 这不是必需的@Marvin
  • 堆栈溢出不是免费的程序编写服务。尝试编写您的程序,如果您遇到困难,那么您可以来这里,发布您的代码,说明您遇到的确切问题并寻求帮助。假设这是编程课上的一个练习,你也可以向你的老师寻求帮助

标签: java loops for-loop recursion


【解决方案1】:

从一个简单的解决方案开始,以下是如何将 3 个嵌套循环解决方案减少为 2 个嵌套循环。

private static void sumUp(int max) {

    sumUp(max, 0,0);
}

private static void sumUp(int maxValue, int k, int counter ) {

    for (int i = 0; i<= maxValue ; i++ ) {

        for (int j = 0; j<= maxValue ; j++ ) {

            if((i+j+k) ==5) {
                System.out.println(i+"+"+j+"+"+k+" = " +(i+j+k));
            }

            counter++;
        }
    }

    k++;
    if(k > maxValue) { return;  }

    sumUp( maxValue, k, counter);
}

通过调用sumUp(3); 进行测试
发布此解决方案是为了简单起见,以明确基本概念。

当然可以进一步改进,只使用递归,没有循环。
编辑 这是一个完整的解决方案,它使用一个循环的递归:

static void sumUp (int max) {
        sumUp(new int[] {0,0,0}, max, 0);
    }

    static void sumUp (  int[] start, int max, int index ) {

        for(int i= start[index] ; i<= max; i += 1) {

            start[index] = i;

            if(index < (start.length-1)) {

                int keep = start[index+1];
                sumUp(start, max, index+1 );
                start[index+1] = keep;

            } else {
                if(IntStream.of(start).sum() == 5) {
                    System.out.println("Sum of "+Arrays.toString(start)+" is 5");
                }
            }
        }
    }

通过调用sumUp(3); 进行测试
输出:

[0, 2, 3] 的和是 5
[0, 3, 2] 的和是 5
[1, 1, 3] 之和为 5
[1, 2, 2] 的和是 5
[1, 3, 1] 的和是 5
[2, 0, 3] 之和为 5
[2, 1, 2] 之和为 5
[2, 2, 1] 的和是 5
[2, 3, 0] 之和为 5
[3,0, 2] 之和为 5
[3, 1, 1] 的和是 5
[3, 2, 0] 之和为 5

【讨论】:

  • 我在上面以一种非常低效的方式使用了递归。您能否建议我进行哪些更改以使其有效。
【解决方案2】:

这是你的作业,我只是做了一个基本的代码(我没有尝试编译它,这只是一个大方向),我也没有加0但你明白了:

public static void main(String []args){
    print(0, new int[3])
 }

 static void print(int num, int[] current){
     if(num == 3){
         if((current[0] + current[1] + current[2]) ==5) print (current);
         return;
     }
     int[] with1 = new int[3];
     int[] with2 = new int[3];
     int[] with3 = new int[3];
     with1[num] = 1;
     with2[num] = 2;
     with3[num] = 3;
     //copy the start of the current array to each new array here
     num++
     print(num,with1);
     print(num,with2);
     print(num,with3);

 }

【讨论】:

    【解决方案3】:

    我不确定这是否是推荐的方式,但您可以获得结果。

    公共类测试{ 公共静态 void main(String args[]) {

        int count = 0;
        for(int i=0; i<=3; i++){
            for(int j=0; j<=3; j++){
                for(int k=0; k<=3; k++){
                    if((i+j+k) == 5){
                        System.out.println("i="+i+","+"j="+j+","+"k="+k);
                        count++;
                    }
                }
            }
        } 
       System.out.println("count = "+count);       
    }
    

    }

    【讨论】:

    • 像这样的三个嵌套for-loops 很少被推荐做某事的方法,而且可能是一个糟糕的解决方案。但是当你这样回答时,你应该扩展:它为什么有效?你的思考过程是什么?对于可能来到这里的其他人,它应该是通用的,以便他们可以轻松地适应他们的需求。另外,请确保文本和代码之间有额外的一行,以便所有代码都这样格式化。
    • 第二个循环for(int j=0; j&lt;=3; j++)只需运行到5-i,第三个循环到5-i-j。可以对 from 进行类似的考虑。如果 i+j 之和为 0,则第三次循环不能成功。 1..3 和 sum=5 的一个小问题,但对于更大的数字则不是这样。优化后,您应该尝试满足条件以使其递归,如问题中所述。
    猜你喜欢
    • 1970-01-01
    • 2021-02-08
    • 1970-01-01
    • 2015-12-30
    • 1970-01-01
    • 2010-12-16
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    相关资源
    最近更新 更多