当前位置: 首页 > 知识库问答 >
问题:

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

司徒兴德
2023-03-14

我有一个方法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是素数这一事实无关紧要。

共有3个答案

宗政永望
2023-03-14

你的返回语句工作正常,但是...你把1,2和3留在了你的逻辑之外。2是偶数,1不是质数。

武琛
2023-03-14

当我们用参数8调用你的函数时,让我们试着看看调用堆栈;

第一个调用是:GetNextTime(8)。由于数字是偶数,该函数进入if部分,并使用GetNextTime(9)再次调用自身。这一次,else部分开始,检查for循环中的可整除性,发现9是可整除的,所以调用getNextTime(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;
}
屠锐
2023-03-14

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

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

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

getNextPrime(++num);

... and ...

getNextPrime(num+2);

换成

return getNextPrime(++num);

... and ...

return getNextPrime(num+2);

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

实现只是一个练习。

 类似资料:
  • 我试图写一个程序,找出给定的数字是否在斐波那契序列中,我不断得到不终止的递归,我不知道为什么。第17行似乎是个大问题。当我输入0或1时,我会得到想要的答案。我只是在寻找答案,我正在努力学习,所以仅仅告诉我答案对我没有多大帮助。

  • 我开始写一个二叉树函数。该方法目前的目标是在树中找到节点并返回节点。根值是数据,左边和右边是子树。当我在调试器中单步执行它时,当它到达return语句时,它会跳回第二个if块,并最终返回null。

  • 请解释返回语句如何为trie的简单递归解析起作用 案例A: 案例B: 案例A对我很有效。但是,我不明白结果被推到堆栈后会发生什么。“it”如何知道终止这些路径?

  • 我在试着测试我正在学习的一门课。我想运行一个打印报表,以员工的月薪乘以12,给我年薪,然后加10%。除了最后一部分,我已经把所有的工作都做好了 线程“main”Java.util.unknownformatconversionexception:Conversion='r'在Java.util.formatter$formatspecier.Conversion(formatter.Java:26

  • 我不得不使用全局变量found来指示在哪里找到了一个和。返回语句始终未定义。 此外,如果在下面的if语句中使用return语句,代码将无法正常工作。 这不是问题的最佳解决方案,但这是我得到的工作版本。 返回语句之间的****,删除时代码工作,否则我要么得到false或未定义。我不明白这部分!为什么删除返回就能解决问题,我认为每个递归调用都必须用返回语句进行。 问题可能是由于多次呼叫造成的吗?我是不

  • 打开和关闭连接: 注册用户 错误消息 '/'应用程序中的服务器错误。 INSERT INTO语句中存在语法错误。 描述:在执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其在代码中的起源的更多信息。 异常详细信息:系统。数据。OleDb。OleDbException:INSERT INTO语句中的语法错误。 源错误: 第100行:命令。ExecuteNonQuery();第1