为什么我在这里得到java.lang.StackOverflowError?
_下面的问题的程序给出了一系列例外情况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
computeFactorial
避免调用factorial
如果R > N
,但称它在所有其他情况下(R == N
,R < N
),传递N-R
。如果R == N
,则N-R
是0
。在factorial
中,您正在检查是否num == 1
和返回1
,但是当num
是0
时,您有factorial
调用本身与num - 1
,这是-1
。然后它会自动再次调用num - 1
,这是-2
等等,并且负数越来越大(-1
,-2
,...),直到您用完堆栈。
我还没有仔细阅读代码,但最起码,你需要有factorial
回报1
时num == 0
以及何时num == 1
(0! = 1
)。如果你给它一个负数,我也会抛出异常。
你能提出一些建议吗? – 2012-02-23 07:06:30
@SuhailGupta:基本上,不要将负数传递给'factorial',并单独更正'factorial',以便它接受'0'并返回正确的结果(像'1!= 1'一样返回正确的结果('0!= 1') )。如果你传递一个负数,我可能也会'factorial'抛出一个异常。我不是数学家,但我不认为你可以采取负数的阶乘;我确定你不能和平常一样'n! = n *(n-1)'公式。 – 2012-02-23 07:27:39
这个答案大部分是正确的 - 你偶尔会调用阶乘(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
您发布的代码有103行,其中有问题的行(105)? – aviad 2012-02-23 06:39:54
因为您正在使用递归方法。要解决它,无论是改进你的代码还是增加堆栈大小。 – 2012-02-23 06:41:13
@ aviad看到编辑。 – 2012-02-23 06:43:58