2012-02-23 187 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 2012-02-23 06:39:54

+0

因爲您正在使用遞歸方法。要解決它,無論是改進你的代碼還是增加堆棧大小。 – 2012-02-23 06:41:13

+0

@ aviad看到編輯。 – 2012-02-23 06:43:58

回答

6

computeFactorial避免調用factorial如果R > N,但稱它在所有其他情況下(R == NR < N),傳遞N-R。如果R == N,則N-R0。在factorial中,您正在檢查是否num == 1和返回1,但是當num0時,您有factorial調用本身與num - 1,這是-1。然後它會自動再次調用num - 1,這是-2等等,並且負數越來越大(-1-2,...),直到您用完堆棧。

我還沒有仔細閱讀代碼,但最起碼​​,你需要有factorial回報1num == 0以及何時num == 10! = 1)。如果你給它一個負數,我也會拋出異常。

+0

你能提出一些建議嗎? – 2012-02-23 07:06:30

+0

@SuhailGupta:基本上,不要將負數傳遞給'factorial',並單獨更正'factorial',以便它接受'0'並返回正確的結果(像'1!= 1'一樣返回正確的結果('0!= 1') )。如果你傳遞一個負數,我可能也會'factorial'拋出一個異常。我不是數學家,但我不認爲你可以採取負數的階乘;我確定你不能和平常一樣'n! = n *(n-1)'公式。 – 2012-02-23 07:27:39

+0

這個答案大部分是正確的 - 你偶爾會調用階乘(0)。由於遞歸在1停止,這永遠不會是好事。如果你將第102行從'if(num == 1){'改爲'if(num == 0){',你的堆棧溢出問題就會消失。關於'R> N'的一點是無關緊要的 - 你已經正確地完成了這部分。但是你也有一個bug - 'return(NFact /(N_Minus_R_Fact-RFact))';'應該說'return(NFact /(N_Minus_R_Fact * RFact));'。另外,如果您希望使代碼更加高效,...(繼續留下評論)... – 2012-02-23 08:01:03

相關問題