代码之家  ›  专栏  ›  技术社区  ›  badProgrammer

Return语句不能正确终止递归方法

  •  1
  • badProgrammer  · 技术社区  · 7 年前

    我有办法 GetNextTime(int num) 它应该标识该方法接收到的值之后最接近的素数。

    如果 数字 是偶数,它将递增它并再次调用自己。如果它是奇数,它将运行for循环来检查它是否可以被3到之间的奇数整除 数字 的半值。如果是,则会增加 数字 则该方法将再次调用自身,否则将返回新的 数字 是质数的值。

    问题是,当程序到达return语句时,它将跳转到if语句并返回 数字 +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语句, 如果(数量%2!=0) 它起作用了。

    为什么会发生这种情况?

    *注意-该方法的值大于3,1、2和3是素数这一事实无关紧要。

    3 回复  |  直到 7 年前
        1
  •  0
  •   Jim Garrison    7 年前

    这里只有一个结构性问题。到达单个返回并不会折叠整个调用堆栈,它只返回到上一次调用。

    您需要保存每次调用getNextTime()的结果,并将其用作返回值,以便实际找到的值沿着调用链传回并返回给初始调用方。目前,您只返回传入的数字,因为您从未修改它。

    修复是一个非常简单的修改。你在哪里

    getNextPrime(++num);
    
    ... and ...
    
    getNextPrime(num+2);
    

    将其替换为

    return getNextPrime(++num);
    
    ... and ...
    
    return getNextPrime(num+2);
    

    您选择的算法的问题是效率低下。您只需要使用较小的素数来测试整除性,而不是所有的奇数,并且只需要使用 平方根 原始编号的。

    实现是一项练习。

        2
  •  0
  •   Anuj    7 年前

    当我们使用参数8调用函数时,让我们看看调用堆栈;

    第一个调用是:getNextTime(8)。由于数字是偶数,该函数进入if部分,并使用getNextTime(9)再次调用自身。这次else部分开始,检查for循环中的可整除性,发现9是可整除的,所以调用getNextPrime(11)。现在getNextTime(11)再次执行else和for循环,发现11是prime,并将数字11返回给调用者,但如果仔细观察,则不会将此值存储在变量中,getNextTime调用中的num变量是9,当getNextTime(9)返回该值时,它会将该值返回给getNextTime(8)。在getNextTime(8)中,也没有真正存储从递归调用堆栈返回的num变量。您只需返回该函数中定义的num变量,在调用getNextTime(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;
    }
    
        3
  •  -1
  •   Aeron Storm    7 年前

    您的返回声明很好,但是。。您在逻辑中遗漏了1、2和3。2是偶数素数,1不是素数。