2012-02-23 10 views
1

次の質問の以下のプログラムは、一連の例外を示しますException in thread "main" java.lang.StackOverflowError at testing_package.Compute.factorial(Compute.java:105)なぜこのエラーが発生するのか分かりません。ここでjava.lang.StackOverflowErrorを取得するのはなぜですか?

質問:N男の子とM女の子は、演劇の演技を学んでいます。演奏を行うには、 は少年少女4人以上、少女少女1人以上を含むP俳優のグループを形成する必要があります。 劇場では、グループを形成する方法の数を知らせるプログラムを書く必要があります。 注:組成は一意であり、組成物の順序ではありません。

import java.io.*; 

class Compute { 

private static int NFact; 
private static int N_Minus_R_Fact; 
private static int RFact; 
private static int fact=0; 

public static int readTheStrengthOfGroup() { 
    int strengthOfGroup=0; 
    try { 
     System.out.println("Enter the strength of group : "); 
     BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 
     String read = reader.readLine(); 
     strengthOfGroup = Integer.parseInt(read); 
    } catch(Exception exc) { 
     System.out.println(exc); 
     } 
     return strengthOfGroup; 
} 

public static int readTheNumberOfBoys() { 
    int boysToParticipate=0; 
    try { 
    System.out.println("Enter the number of boys to participate in the play : "); 
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 
    String read = reader.readLine(); 
    boysToParticipate = Integer.parseInt(read); 
    } catch(Exception exc) { 
     System.out.println(exc); 
    } 
    return boysToParticipate; 
} 

public static int readTheNumberOfGirls() { 
    int girlsToParticipate=0; 
    try { 
     System.out.println("Enter the number of girls to participate in the play : "); 
     BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 
     String read = reader.readLine(); 
     girlsToParticipate = Integer.parseInt(read); 
    } catch(Exception exc) { 
     System.out.println(exc); 
     } 
    return girlsToParticipate; 
} 

public static int compute(int strengthOfGroup , int boysToParticipate , int girlsToParticipate) { 
    if(boysToParticipate < 4 || girlsToParticipate < 1) { 
     return 0; 
    } else { 
     /* P >= 5 
     * N : Boys 
     * M : Girls 
     * result = M+N C P - { (N C 0)(M C P)+(N C 1)(M C P-1)+(N C 2)(M C P-2)+(N C 3)(M C P-3)+(N C P)(M C 0) } 
     */ 
     int resultP_2 = 0; 
     int totalNumberOfParticipants = boysToParticipate + girlsToParticipate; 
     int totalNumberOfParticipants_C_strengthOfGroup = computeFactorial(totalNumberOfParticipants , strengthOfGroup); 
     for(int i = 0 ; i <= 4 ; i++) { 
          if(i == 4) { 
       resultP_2 = resultP_2 + (computeFactorial(boysToParticipate,strengthOfGroup) * computeFactorial(girlsToParticipate,0)); 
      }else { 
      resultP_2 = resultP_2 + (computeFactorial(boysToParticipate,i) * computeFactorial(girlsToParticipate,strengthOfGroup)); 
      strengthOfGroup--;} 
     } 
     int result = totalNumberOfParticipants_C_strengthOfGroup - resultP_2; 
     return result; 
     } 
} 

public static int computeFactorial(int N , int R) { 
    if(R > N) { 
     throw new RuntimeException("Invalid Parameters"); 
    } else { 
     /* int NFact; 
     int N_Minus_R_Fact; 
     int RFact; */ 
     NFact = factorial(N); 
     N_Minus_R_Fact = factorial(N-R); 
     RFact = factorial(R); 
     return(NFact/(N_Minus_R_Fact-RFact)); 

     } 
} 

public static int factorial(int num) { 
    if(num == 1) { 
     return 1; 
    } else { 
     fact = num * factorial(num-1); // LINE 105 
     return fact; 
     } 
} 

public static void main(String args[]) { 
    int strengthOfGroup = readTheStrengthOfGroup(); 
    int boysToParticipate = readTheNumberOfBoys(); 
    int girlsToParticipate = readTheNumberOfGirls(); 
    int result = compute(strengthOfGroup , boysToParticipate , girlsToParticipate); 
    System.out.println("Number of groups that can be formed : " + result); 
} 

}

私は、行番号105 enter image description here

+2

投稿したコードには103行あり、問題のある行はどこですか(105)? – aviad

+0

再帰的メソッドを使用しているためです。それを解決するには、コードを改善するか、スタックサイズを増やすかどうか。 –

+0

@ aviad編集を参照してください。 –

答えて

6

computeFactorialをコメントしているR > N場合factorialを呼び出して回避するがN-Rに渡して、他のすべてのケース(R == NR < N)でそれを呼び出します。 R == Nの場合、N-R0です。 factorialでは、num == 1場合と1を返すチェックしているが、num0あるとき、あなたは-1あるnum - 1factorialコール自体を、抱えています。 num - 1-2)などのように再び呼び出され、スタックがなくなるまで、負の数値(-1-2、...)が順調に増加します。

私は密接にコードを読んでいないが、非常に少なくとも、あなたはfactorialリターン1num == 0などnum == 10! = 1)を持っている必要があります。また、負の数を入力すると例外がスローされます。

+0

何か提案できますか? –

+0

@SuhailGupta:基本的に、負の数を 'factorial'に渡さず、' factorial'を '0 'を受け取り、正しい結果(' 1!= 1'のように '0!= 1' )。私はおそらくあなたが負の数を渡す場合、 '階乗'例外をスローするだろう。私は数学者ではありませんが、負の数の階乗をとることはできません。私はあなたがいつもの 'n! = n *(n-1) 'の公式。 –

+0

この答えは大抵正確です - 今は毎回factorial(0)を呼び出します。再帰は1で終わるので、これは決して良いことではありません。行102を 'if(num == 1){'から 'if(num == 0){'に変更すると、スタックオーバーフローの問題はなくなります。 'R> N 'に関するビットは無関係です - あなたはこの部分を正しく行っています。しかし、もう1つのバグもあります。「return(NFact /(N_Minus_R_Fact * RFact));」という行は、 'return(NFact /(N_Minus_R_Fact * RFact));また、コードをもっと効率的にしたい場合は...(コメント続き)... –