2012-02-23 4 views
1

_Le programme suivant de la question ci-dessous donne une série d'exceptions Exception in thread "main" java.lang.StackOverflowError at testing_package.Compute.factorial(Compute.java:105) Je ne comprends pas pourquoi j'obtiens cette erreur.pourquoi je reçois java.lang.StackOverflowError ici?

Question: N garçons et M filles apprennent des compétences d'acteur d'un théâtre. Pour jouer une pièce , ils doivent former un groupe d'acteurs P contenant pas moins de 4 garçons et pas moins de 1 fille. Le théâtre vous oblige à écrire un programme qui leur indique le nombre de façons dont le groupe peut être formé. Note: La composition doit être unique et non l'ordre dans lequel la composition est faite.

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

}

J'ai commenté le numéro de ligne 105. enter image description here

+2

le code que vous avez posté comporte 103 lignes, où est la ligne problématique (105)? – aviad

+0

Parce que vous utilisez une méthode récursive. Pour le résoudre, que ce soit améliorer votre code ou augmenter la taille de la pile. –

+0

@ aviad voir la modification. –

Répondre

6

computeFactorial évite d'appeler factorial si R > N, mais il appelle dans tous les autres cas (R == N, R < N), en passant N-R. Si R == N, alors N-R est 0. En factorial, vous vérifiez si num == 1 et le retour 1, mais quand num est 0, vous éprouvez factorial appel lui-même avec num - 1, qui est -1. Puis il s'appelle à nouveau avec num - 1, qui est -2, et ainsi de suite avec des nombres négatifs de plus en plus grands (-1, -2, ...) jusqu'à ce que vous soyez à court de pile.

Je n'ai pas lu le code près, mais vous devez avoir factorial retour 1 à tout le moins lorsque num == 0 ainsi que lors num == 1 (0! = 1). Je l'aurais aussi jeter une exception si vous lui donnez un nombre négatif.

+0

pouvez-vous suggérer quelque chose? –

+0

@SuhailGupta: Fondamentalement, ne pas passer des nombres négatifs dans 'factorial', et corriger séparément' factorial' de sorte qu'il accepte '0' et renvoie le résultat correct (' 0! = 1' juste comme '1! = 1'). J'aurais probablement aussi 'factorial' jeter une exception si vous lui passez un nombre négatif. Je ne suis pas un mathématicien, mais je ne pense pas que vous puissiez prendre la factorielle d'un nombre négatif; Je suis certain que vous ne pouvez pas avec l'habituel 'n! = n * (n - 1) 'formule. –

+0

Cette réponse est la plupart du temps correcte - de temps en temps, vous finissez par appeler factorielle (0). Puisque la récursivité s'arrête à 1, cela ne va jamais être bon. Si vous changez la ligne 102 de 'if (num == 1) {' à 'if (num == 0) {', votre problème de débordement de pile disparaîtra. Le bit sur 'R> N' n'est pas pertinent - vous avez correctement fait cette partie. Mais vous avez aussi un autre bug - la ligne qui dit 'return (NFact/(N_Minus_R_Fact-RFact)),' devrait dire 'return (NFact/(N_Minus_R_Fact * RFact));'. Aussi, si vous voulez rendre le code beaucoup plus efficace, ... (commentaire continué) ... –

Questions connexes