Java 找到使用1,5,10,25,50美分获得17美分的方法(例如)

Java 找到使用1,5,10,25,50美分获得17美分的方法(例如),java,recursion,dynamic,dynamic-programming,recurrence,Java,Recursion,Dynamic,Dynamic Programming,Recurrence,为什么会出现堆栈溢出错误问题是,在我开始使用动态规划之前,我试图递归地解决这个问题。在方法coins中,“a”是保存硬币的数组,硬币将构成我想要的总数,sum是我想要的总数(例如17),我表示我所在数组的索引 import java.util.*; public class dp2 {//RECURSIVE WAY THEN OPTIMIZE TO DP public static int coins (int [] a, int sum,int i){ if (sum==0)

为什么会出现堆栈溢出错误问题是,在我开始使用动态规划之前,我试图递归地解决这个问题。在方法coins中,“a”是保存硬币的数组,硬币将构成我想要的总数,sum是我想要的总数(例如17),我表示我所在数组的索引

import java.util.*;
public class dp2 {//RECURSIVE WAY THEN OPTIMIZE TO DP
  public static int coins (int [] a, int sum,int i){

    if (sum==0)
        return 1;
    else if (i==a.length){
        return 0;
    }
    else if (i>a.length&&sum<a[i]){
        return coins(a,sum,i++);
    }

    else {
        return coins(a,sum-a[i],i++)+coins(a,sum-a[i],i);
    }
  }

  public static void main (String [] args ){
    Scanner sc = new Scanner (System.in);

    while (sc.hasNext()){
        int x = sc.nextInt();
        int y=x;
        int [] a ={1,5,10,25,50};
        int w = coins(a,y,0);
        System.out.println("There are " +w+ " ways to produce "+x + " coins change.");
    }               
  }

}
import java.util.*;
公共类dp2{//递归方式然后优化为DP
公共静态整数硬币(整数[]a,整数和,整数i){
如果(总和=0)
返回1;
else if(i==a.length){
返回0;
}

否则,如果(i>a.length&&sum您对无限循环有问题

首先检查,您想要返回什么,因为实际上您只能返回1或0。那么,其他条件在哪里?例如:i==a.length-1或sum<0?我想,您想要返回sum

接下来,若你们把例子17放进去,那个么从你们可以选择的阵列中选择巫婆硬币的机制在哪里呢

接下来,请更改
返回硬币(a,sum-a[i],++i)+硬币(a,sum-a[i],i);
,因为在您的代码中i始终为0

因此,也许这是一个很好的示例代码:

class dp2 {//RECURSIVE WAY THEN OPTIMIZE TO DP
  public static int coins (int [] a, int sum,int i){
    if (sum==0)
        return 1;
    else if (i==a.length){
        return 0;
    }else if(i + 1 == a.length || sum < 0 || sum - a[i] < 0){ //Your break condition ?
        return sum;
    }
    else if (i>a.length&&sum<a[i]){
        return coins(a,sum,i++);
    }

    else {
        return coins(a,sum-a[i],++i)+coins(a,sum-a[i],i);
    }
  }
  public static void main (String [] args ){
    Scanner sc = new Scanner (System.in);

    while (sc.hasNext()){
        int x = sc.nextInt();
        int y=x;
        int [] a ={1,5,10,25,50};
        int w = coins(a,y,0);
        System.out.println("There are " +w+ " ways to produce "+x + " coins change.");
    }
  }
}
类dp2{//递归方式,然后优化为DP
公共静态整数硬币(整数[]a,整数和,整数i){
如果(总和=0)
返回1;
else if(i==a.length){
返回0;
}如果(i+1==a.length | | | sum<0 | | | sum-a[i]<0){//你的中断条件?
回报金额;
}

否则,如果(i>a.length&&sum我在代码第4行添加了一条语句:

System.out.println(sum + ", " + i);
给出输入27,输出为:

27, 0
26, 0
25, 0
.... decreasing by one each time...
3, 0
2, 0
1, 0
0, 0
-4, 1
-9, 1
-14, 1
然后它永远不会停止,因为您不检查
sum<0


你应该能够从那里找到答案…
println
:世界上最轻的调试器:-)

这可能是一个无限递归调用,检查你的条件(你的代码,你应该比我们更快地发现问题)。或者可能是大量递归调用,但这不太可能导致堆栈过载。使用debugged跟踪调用这是一个无限递归调用。请注意:您应该坚持使用一种方法格式化单行语句(我建议始终使用大括号)因为混合可能会导致混乱和难以发现错误。我的意思是,像这样的事情你的第一个if块,而不是后面的else-if块。我无法找出我的条件有什么问题。我检查了几次尝试调试它我的代码中有一行;else-if(虽然这不是终止条件,但它只会导致对
coins
的另一个调用。如果递归函数跑掉并溢出堆栈,您需要首先检查终止条件,然后修复沿途发现的任何其他问题。对于终止,我有两个条件,当总和为零时,iYou wi如果我告诉你的话,你自己会明白更多。向代码中添加更多的
println
s,在四个分支中各添加一个,这样你就知道代码的去向。也许添加另一个参数只是为了跟踪调用深度。请注意,在我的示例输出中,
sum
的值确实达到了零,因此至少有一个invoca在那一点上,
硬币的组合返回了1。接下来发生了什么?问题是我不想跟踪我将选择哪种硬币我只想知道我可以组合这些硬币的方法的数量,以形成我在减去时的总和(sum-a[i])我减少总和直到它达到零,一旦它达到零,然后我返回一。两种可能的方法是,要么我多次使用同一枚硬币,要么转到下一枚硬币:返回硬币(a,sum-a[i],i)+硬币(a,sum-a[i],++i);好的,增量和中断条件仍然存在相同的问题。因此,我给出两个建议:1)关于增量,2)关于中断条件:)