[英]How to correctly place a return statement in a recursive method with if\else conditions
[英]Return statement does not correctly terminate a recursive method
我有一个方法getNextPrime(int num) ,该方法应该标识该方法接收到的值之后最接近的素数。
如果num是偶数,它将增加它并再次调用自身。 如果它是奇数,它将运行for循环以检查它是否可以被3到num的一半值之间的奇数整除。 如果是,则它将使num增加2,并且该方法将再次调用自身,否则它将返回作为质数的新num值。
问题是,当程序到达return语句时,它将跳至if语句并返回num + 1的原始值。我已经调试了一段时间,但这没有任何意义。 无论我在何处放置return语句,该方法都将跳转到if语句,而不是终止该方法并将值返回到从其调用的位置。
public int getNextPrime(int num){
if(num % 2 == 0){
//even numbers are not prime
getNextPrime(++num);
}
else{
for(int i = 3; i < (num + 1) / 2; i += 2){
if(num % i == 0) {
getNextPrime(num += 2); //consider odd numbers only
}
}
}
return num; //jumps to if and terminates
}
但是,如果我将else语句更改为单独的if语句, 则if(num%2!= 0)起作用。
为什么会这样?
*注意-给该方法的值大于3,则1、2和3是质数这一事实无关紧要。
这里只有一个结构性问题。 到达单个返回不会折叠整个调用堆栈,它只会返回到先前的调用。
您需要保存每次调用getNextPrime()的结果并将其用作返回值,因此实际找到的值将沿着调用链传递回并返回给初始调用者。 照原样,您只返回传入的数字,因为您从未修改过它。
该修复程序是非常简单的修改。 你在哪里
getNextPrime(++num);
... and ...
getNextPrime(num+2);
替换为
return getNextPrime(++num);
... and ...
return getNextPrime(num+2);
您选择的算法的问题在于效率低下。 您只需要使用较小的质数而不是所有奇数,并且仅使用原始数的平方根来测试可除性。
实施是一项练习。
让我们尝试看一下我们使用参数8调用函数时的调用堆栈;
第一个调用是:getNextPrime(8)。 由于数字是偶数,该函数进入if部分,然后使用getNextPrime(9)再次调用自身。 这次,其他部分启动,在for循环中检查可除性,发现9是可整除的,因此调用getNextPrime(11)。 现在,getNextPrime(11)再次进入else和for循环,发现11是质数,并将数字11返回给调用方,但是如果仔细观察,则不会将此值存储在变量中,而num变量存储在getNextPrime调用为9,当getNextPrime(9)返回时,该值返回给getNextPrime(8)。 在getNextPrime(8)中,您也没有真正存储从递归调用堆栈返回的num变量。 您只是返回该函数中定义的num变量,您恰巧在调用getNextPrime(11)之前将其递增,因此该值为9,并返回9。
下面给出了具有相同if else块的更正程序,以供您参考。
public static int genNextPrime(int num) {
if (num % 2 == 0) {
num = genNextPrime(++num);
} else {
for (int i = 3; i < (num + 1) / 2; i += 2) {
if (num % i == 0) {
num += 2;
num = genNextPrime(num);
}
}
}
return num;
}
您的return语句工作正常,但是..您将1,2和3遗漏了。 2是偶数质数,而1不是质数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.