【问题标题】:Print 2 closest, smaller Fibonacci numbers打印 2 个最接近、较小的斐波那契数
【发布时间】:2018-03-13 21:54:00
【问题描述】:

我很难找到解决这个问题的方法。我需要编写一个迭代(不能使用递归)解决方案来解决用户通过扫描仪输入数字(例如 10)并打印 2 个“以前的”Fib 数字的问题。

对于输入“10”的例子,它将是:

5
8

因为它们是 10 之前“最大”的两个 Fib 数字。

如果输入是 13,它将打印:

8
13

由于 13 本身就是一个 Fib 数字,所以它只先打印 1 个数字,然后再打印它自己。

现在我知道如何迭代地找到“第 n 个”Fib 号码,但我无法想到一个解决方案来运行直到给定数字(而不是第 n 个 Fib 号码)并以某种方式只打印在它之前的最后 2 个(或者,如果给定的数字本身就是一个 Fib 数字,那么也算作一个)。

现在我知道使用完美正方形的公式 - 但不幸的是,不能使用它...

编辑,因为它让一些人感到困惑:

我不要求提供代码,也不希望任何人为我解决这个问题。我只是真的想了解如何处理这些问题。

编辑#2:

这是我写的代码:

int a = 0;
int b = 1;

while (a < num) {
    int temp = a;
    a = a + b;
    b = temp;
}
System.out.println(b);
System.out.println(a);

我遇到的问题是,如果 num 输入确实是 Fib num - 它会按预期工作,否则,它会打印 1 个之前的 Fib num 和下一个,因此对于输入“10”,它会打印 8 和13.

【问题讨论】:

  • Stack Overflow 是一个问答网站,而不是家庭作业写作服务。如果你认为我们会为你做功课,那你就大错特错了。 An open letter to students with homework problems
  • @JoeC 虽然我非常理解您的观点和这封信,但我确实进行了研究,并且知道不同的方法。我不要求完整的代码,只是帮助理解正确的方法以及如何处理此类问题。
  • 那么你需要edit你的问题来显示所有这些。就目前而言,这似乎是一个“给我代码”的问题,如果没有证据表明已经做出努力,你就有可能被关闭。
  • 我的方法——在考虑编写代码之前广泛在纸上找出逻辑。玩数学,阅读大量纸,它通常会出现在你身上。
  • 我不明白这个问题。你说你已经有了一个计算所有 Fibs 迭代的公式。然后这样做并在到达某个大于等于输入的 Fib 时停止。发生这种情况时,输出你总是记住的最后两个计算的 Fib。如果该描述没有帮助,您可能需要特定解决方案。但这只有在您先向我们展示您的代码时才有可能。

标签: java fibonacci


【解决方案1】:

说明

您说您已经有一个计算n-th 斐波那契数迭代的方法。由于斐波那契数通常是根据最后两个斐波那契元素定义的,因此您也应该已经拥有它们,请参阅 Wikipedia 中的定义:

您唯一需要做的就是运行您的迭代方法,直到您到达输入。然后输出F_(n - 1)F_(n - 2)(或F_n如果等于输入)的当前记忆值。


示例

假设你有一个斐波那契方法(我从第一个谷歌结果中获取)

public static long fib(int n) {
    if (n <= 2) {
        return (n > 0) ? 1 : 0;
    }
    long fib1 = 0;
    long fib2 = 1;
    for (int i = 1; i < n; i++) {
        final long newFib = fib1 + fib2;
        fib1 = fib2;
        fib2 = newFib;
    }
    return fib2;
}

您需要修改它以接受input 并返回最后一个斐波那契数fib1fib2。用一个无限循环替换循环到n,一旦超过input,你就会中断:

public static long[] fib(long input) {
    // Special cases
    if (input == 1) {
        return new long[] { 1l, 1l };
    }
    if (input == 0) {
        return new long[] { 0l };
    }
    if (input < 0) {
        return null;
    }

    // Seed values
    long fib1 = 0;
    long fib2 = 1;

    // Repeat until return
    while (true) {
        long newFib = fib1 + fib2;

        // Reached the end
        if (newFib >= input) {
            // Push 'newFib' to the results
            if (newFib == input) {
                fib1 = fib2;
                fib2 = newFib;
            }
            return new long[] { fib1, fib2 };
        }

        // Prepare next round
        fib1 = fib2;
        fib2 = newFib;
    }
}

该方法现在在[0] 返回第二个最接近的斐波那契数,在[1] 返回最接近input 的斐波那契数。

您也可以使用此示例轻松调整自己的方法。


用法:

public static void main(String[] args) {
    long[] results = fib(20L);
    // Prints "8, 13"
    System.out.println(results[0] + ", " + results[1]);

    results = fib(21L);
    // Prints "13, 21"
    System.out.println(results[0] + ", " + results[1]);
}

另一个例子

使用某种nextFib 方法可以获得对同一问题的不同看法。然后你可以反复选择直到超过input。因此,我们构建了一些类似

的类
public class FibonacciCalculator {
    private long fib1 = 0;
    private long fib2 = 1;
    private int n = 0;

    public long nextFib() {
        // Special cases
        if (n <= 2) {
            long result = (n > 0) ? 1 : 0;
            // Increase the index
            n++;
            return result;
        }

        // Compute current and push
        long newFib = fib1 + fib2;
        fib1 = fib2;
        fib2 = newFib;

        return newFib;
    }
}

然后我们只调用它直到超过input,总是记住最后两个值:

public static long[] fib(long input) {
    FibonacciCalculator calc = new FibonacciCalculator();
    long lastFib = 0L;
    long secondToLastFib = 0L;

    while (true) {
        long curFib = calc.nextFib();

        if (curFib > input) {
            return new long[] { secondToLastFib, lastFib };
        } else if (curFib == input) {
            return new long[] { lastFib, curFib };
        }

        secondToLastFib = lastFib;
        lastFib = curFib;
    }
}

【讨论】:

  • 所以我写了这样的东西:` int a = 0;诠释 b = 1; while (a
  • 不要在评论部分发布代码,而是发布一些带有代码格式的网站的链接。或编辑您的问题。问题很明显,你总是删除secondToLast fib,即使a 严格大于num。在这种情况下,您应该保留它(请参阅我的示例中的 if 语句)。
  • 我编辑了我的原始帖子。不幸的是,我仍然无法说出我的问题是什么......
  • 如果您将算法执行写在纸上,可能会有所帮助。如果a 严格超过num (a &gt; num),那么您已经将a 设置为更大的数字。所以,当你离开循环时,a 是那个更大的数字。但是您只希望在a == num 的情况下使用它,否则您不希望a 成为更大的数字。您可以通过检查循环内的条件(然后拒绝将a 分配给更大的数字)或记住最后三个小窍门而不是最后两个小窍门来解决此问题。然后,如果fib1 超过num,您可以退回到{fib2, fib3} 而不是{fib1, fib2}
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-04
  • 2017-10-13
  • 1970-01-01
  • 2012-02-15
  • 2020-03-01
相关资源
最近更新 更多