2017-01-20 7 views
-1

왜 스택 오버플로 오류가 발생합니까? 제가이 문제를 시작으로 재귀 적으로 해결하려고 시도하는 이유는 무엇입니까? 동적 인 프로그래밍을 사용하여 시작합니다. 방법 동전에서 "a"는 내가 원하는 총을 형성 할 동전을 보유하는 배열이고, sum은 내가 원하는 총 (예 : 17)이고, i는 그 배열의 색인을 나타냅니다. 오전에find 1,5,10,25,50 센트를 사용하여 총 17cents (예 :)를 얻는 방법의 수

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."); 
    }    
    } 

} 
+1

:-) 세계에서 가장 가벼운 무게 디버거, 당신은해야한다, (코드를 당신의 상태를 확인 우리보다 더 빨리 문제를 찾으십시오). 또는 많은 재귀 호출이 될 수 있지만 스택 오버로드가 발생하지는 않습니다. 디버깅을 사용하여 호출을 추적하십시오. – AxelH

+0

이것은 무한 재귀 호출입니다. –

+0

한 가지 조언을 부탁합니다. 한 줄짜리 문장을 작성하는 한 가지 방법을 고집해야합니다. 혼합하면 혼동을 일으키고 버그를 찾기 어렵 기 때문에 항상 중괄호를 사용하는 것이 좋습니다. 제 말은 첫 번째 if-block이 else-if-block과 반대되는 것입니다. – Thomas

답변

0

무한 루프에 문제가 있습니다.

첫 번째 확인, 실제로 반환 할 수있는 것은 실제로 1 또는 0 만 반환 할 수 있기 때문입니다. 다른 조건은 어디에 있습니까? 예 : i == a.length - 1 또는 합계 <? 제 생각에, 당신은 합계를 돌려주고 싶습니다.

다음으로 예 17을 입력하면 배열에서 마녀 동전을 선택할 메커니즘을 선택할 수 있습니까?

그리고 다음, 내가이 항상 있기 때문에 코드에서, return coins(a,sum-a[i],++i)+coins(a,sum-a[i],i);을 변경하십시오 0

그래서, 어쩌면 당신을 위해 좋은 exaple 코드 : 난 당신의 코드를 하나 개의 문장을 추가

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."); 
    } 
    } 
} 
+0

것은 내가 원하는 동전을 추적하고 싶지 않다. 단지 내가이 동전들을 조합해서 조합 할 수있는 방법의 수를 알고 싶다. 근본적으로 내가 뺄 때 (sum-a [i]) 그것이 제로에 도달하면 제로에 도달 할 때까지 합계를 줄입니다. 그러면 두 가지 가능한 방법 중 하나를 반환합니다. 동일한 동전을 두 번 이상 가져 가거나 다음 동전으로 이동합니다 : 동전 (a, sum-a [i], i)) + 동전 (a, sum-a [i], ++ i); – marwagaser

+0

그래도 증분 및 중단 조건과 동일한 문제가 있습니다. 그래서, 나는 두 가지 조언을한다 : 1) 증분, 2) 중단 조건에 대해서 :) – MateuszW90

0

, 행 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 그것을 알아낼 수 있어야한다 : 이것은 아마도 무한 재귀 호출이다

+0

나는 내 코드에 한 줄을 가지고있다. else if (i marwagaser

+0

그것은 종료 조건이 아닙니다. '동전 '에 대한 또 다른 호출. 재귀 함수가 실행되어 스택을 오버플로하면 초기에 종료 조건을 확인한 다음 다른 문제를 해결해야합니다. –

+0

종결에 대한 합계는 0과 i marwagaser