【问题标题】:Return statement doesn't break out of block, even though condition is true即使条件为真,返回语句也不会脱离块
【发布时间】:2014-09-06 04:57:14
【问题描述】:

这是一个检查数字是否为斐波那契的简单程序。我有一个神秘的错误:“return true”语句没有被触发。相反,“hi”会被打印很多次。回报应该突破方法,有没有人知道为什么它不是?谢谢!

import java.util.*;
public class Solution {

public static boolean listFibs (long oldestFib, long oldFib, long input) {
    long newFib = oldestFib + oldFib;

    while (newFib < Math.pow(10,10)) {

        if (newFib == input) {
            System.out.println("hi");
            return true;
        }

        listFibs(oldFib, newFib, input);
    }

    return false;  
}


public static void main(String[] args) {
    /*Scanner in = new Scanner(System.in);
    int testCases = in.nextInt();
    for (int i = 0; i < testCases; i++) {
        int a = in.nextInt();
        System.out.println("A=  " + a);
        System.out.println(listFibs(0, 1, a));
    }*/

    System.out.println(listFibs(0, 1, 5));

} }

【问题讨论】:

  • 是的——我在hackerrank环境和我的本地IDE中都试过了。它对你有用吗?
  • Math.pow 10 10 总是 10 pow 10,你在那里尝试什么?
  • 只检查不超过 10^10 的数字。
  • 用英文告诉我们你的整个算法?
  • 我几乎可以肯定问题出在您的 while 循环上,因为如果 newfib != 输入,那么它将创建 10^10 个具有相同输入的相同函数实例。你应该用 if 替换 while ,那应该很好。

标签: java math return fibonacci


【解决方案1】:

由于递归,listFibs 有许多化身。 return 只留下其中之一。

在给出的示例中,您会收到以下调用:

listFib(0,1,5)
  listFib(1,1,5)
    listFib(1,2,5)
      listFib(2,3,5)
      -> true
      listFib(2,3,5) // called again due to the loop
      -> true
      listFib(2,3,5) // called again due to the loop
      -> true
      listFib(2,3,5) // called again due to the loop
      -> true
      listFib(2,3,5) // called again due to the loop
      ...

【讨论】:

  • 您能进一步解释一下吗?我认为 return 语句会阻止它一旦变为 true 就不会再次调用自己。
  • 这就是重点。它不会再调用自己,但是该函数的实例会调用自己。
  • 递归是方法的“嵌套”。 listFibs 的每个实例都是不同的,即使其他实例已经返回,它们也会执行其功能。递归可能会令人困惑,您应该查看一些文档...尝试introcs.cs.princeton.edu/java/23recursion
  • 这是否意味着递归执行它所花费的时间是非递归方法的两倍?
【解决方案2】:

实际上,如果多次打印“hi”,则必须同时执行return语句。如果您在该 return 语句中安装一个断点,您会看到。
你的函数是recursion,“listFibs”会被调用很多次。

【讨论】:

    【解决方案3】:

    打印方法中所有 3 个变量的值,你就会知道哪里出了问题。您正在使用递归,看看它被调用了多少次。

    另外,在调用listFib 之后,执行将再次进入while 循环。你至少需要说return listFibs。在您的 listFibs 和 while 循环条件之间,没有任何变化。 2,3,5 一次又一次地被发现。

    http://ideone.com/1d440f

    【讨论】:

    • 对——但是 return true 应该跳出方法,所以一旦找到斐波那契数就不会发生递归调用?
    • 递归就像一棵树,一旦找到叶子,就必须从那里展开
    【解决方案4】:

    您还差一步...递归调用不会对您从 listFibs 获得的结果执行任何操作,因此程序会看到如下内容:

    while (newFib < Math.pow(10,10)) {
    
        if (newFib == input) {
            System.out.println("hi");
            return true;
        }
    
        true //or false
    }
    

    尝试添加这个额外的小 IF 语句。一旦找到一个真实的结果,它将被传回链并传出函数。

    while (newFib < Math.pow(10,10)) {
    
        if (newFib == input) {
            System.out.println("hi");
            return true;
        }
    
        if listFibs(oldFib, newFib, input){
            return true;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-03
      • 1970-01-01
      相关资源
      最近更新 更多