简体   繁体   English

Return语句无法正确终止递归方法

[英]Return statement does not correctly terminate a recursive method

I have a method getNextPrime(int num) which is supposed to identify the closest prime number after the value received by the method. 我有一个方法getNextPrime(int num) ,该方法应该标识该方法接收到的值之后最接近的素数。

If num is even, it will increment it and call itself again. 如果num是偶数,它将增加它并再次调用自身。 If it is odd, it will run a for loop to check if it is divisible by odd numbers between 3 and num 's half value. 如果它是奇数,它将运行for循环以检查它是否可以被3到num的一半值之间的奇数整除。 If it is then it will increase num by 2 and the method will call itself again, otherwise it will return the new num value which is a prime number. 如果是,则它将使num增加2,并且该方法将再次调用自身,否则它将返回作为质数的新num值。

The problem is, when the program gets to the return statement, it will jump to the if statement and return the original value of num + 1. I have been debugging this for a while and it just doesn't make sense. 问题是,当程序到达return语句时,它将跳至if语句并返回num + 1的原始值。我已经调试了一段时间,但这没有任何意义。 Wherever I place the return statement, the method just jumps to the if statement instead of terminating the method and returning the value to where it is being called from. 无论我在何处放置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
}

However, if I change the else statement to a separate if statement, if(num % 2 != 0) it works. 但是,如果我将else语句更改为单独的if语句, 则if(num%2!= 0)起作用。

Why does this happen? 为什么会这样?

*Note - the values given to the method are greater than 3, the fact that 1, 2, and 3 are primes doesn't matter. *注意-给该方法的值大于3,则1、2和3是质数这一事实无关紧要。

There is only one structural problem here. 这里只有一个结构性问题。 Reaching a single return does not collapse the entire call stack, it only returns to the previous invocation. 到达单个返回不会折叠整个调用堆栈,它只会返回到先前的调用。

You need to save the result of calling getNextPrime() every time and use that as the return value, so the value actually found gets passed back along the call chain and returned to the initial caller. 您需要保存每次调用getNextPrime()的结果并将其用作返回值,因此实际找到的值将沿着调用链传递回并返回给初始调用者。 As it stands you return only the number that was passed in since you never modify it. 照原样,您只返回传入的数字,因为您从未修改过它。

The fix is a very simple modification. 该修复程序是非常简单的修改。 Where you have 你在哪里

getNextPrime(++num);

... and ...

getNextPrime(num+2);

replace them with 替换为

return getNextPrime(++num);

... and ...

return getNextPrime(num+2);

The problem with the algorithm you chose is that it is inefficient. 您选择的算法的问题在于效率低下。 You need to test divisibility using smaller primes only, not all odd numbers, and only up to the square root of the original number. 您只需要使用较小的质数而不是所有奇数,并且仅使用原始数的平方根来测试可除性。

Implementation is left as an exercise. 实施是一项练习。

Lets try to look at the call stack when we call your function with argument 8; 让我们尝试看一下我们使用参数8调用函数时的调用堆栈;

The first call is : getNextPrime(8). 第一个调用是:getNextPrime(8)。 As the number is even, the function goes into the if part and calls itself again with getNextPrime(9). 由于数字是偶数,该函数进入if部分,然后使用getNextPrime(9)再次调用自身。 This time the else part kicks in, checks for divisibility in for loop, finds that 9 is divisible so calls the getNextPrime(11). 这次,其他部分启动,在for循环中检查可除性,发现9是可整除的,因此调用getNextPrime(11)。 Now getNextPrime(11) goes again the else and the for loop and finds that 11 was prime and returns the number 11 to the caller, but if you look closely, you don't store this value in a variable, the num variable in the getNextPrime call was 9, and when getNextPrime(9) returns it returns that value to getNextPrime(8). 现在,getNextPrime(11)再次进入else和for循环,发现11是质数,并将数字11返回给调用方,但是如果仔细观察,则不会将此值存储在变量中,而num变量存储在getNextPrime调用为9,当getNextPrime(9)返回时,该值返回给getNextPrime(8)。 In your getNextPrime(8) too you haven't really stored the num variable returned from the recursion call stack. 在getNextPrime(8)中,您也没有真正存储从递归调用堆栈返回的num变量。 You are just return the num variable defined in that function, which you happened to increment before calling the getNextPrime(11) so this value is 9, and 9 is returned. 您只是返回该函数中定义的num变量,您恰巧在调用getNextPrime(11)之前将其递增,因此该值为9,并返回9。

Corrected program with the same if else block is given below for your reference. 下面给出了具有相同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;
}

Your return statement works fine but ..you have left 1,2 and 3 out of your logic. 您的return语句工作正常,但是..您将1,2和3遗漏了。 2 is a even prime number and 1 is not a prime number. 2是偶数质数,而1不是质数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM