Java 确定一个数是否为斐波那契数

Java 确定一个数是否为斐波那契数,java,fibonacci,Java,Fibonacci,我需要编写一个Java代码来检查用户输入的数字是否在斐波那契序列中 我没有问题将斐波那契数列写入输出,但是(可能是因为它在深夜),我正在努力思考“是否”是斐波那契数的序列。我一次又一次地开始。这真让我头疼 我现在拥有的是第n个 public static void main(String[] args) { ConsoleReader console = new ConsoleReader(); System.out.println("Enter the value for y

我需要编写一个Java代码来检查用户输入的数字是否在斐波那契序列中

我没有问题将斐波那契数列写入输出,但是(可能是因为它在深夜),我正在努力思考“是否”是斐波那契数的序列。我一次又一次地开始。这真让我头疼

我现在拥有的是第n个

public static void main(String[] args)
{
    ConsoleReader console = new ConsoleReader();

    System.out.println("Enter the value for your n: ");
    int num = (console.readInt());
    System.out.println("\nThe largest nth fibonacci: "+fib(num));
    System.out.println();
}

static int fib(int n){
    int f = 0;
    int g = 1;
    int largeNum = -1;
    for(int i = 0; i < n; i++)
    {
      if(i == (n-1))
          largeNum = f;
      System.out.print(f + " ");
      f = f + g;
      g = f - g;
    }
    return largeNum;
}
publicstaticvoidmain(字符串[]args)
{
ConsoleReader控制台=新的ConsoleReader();
System.out.println(“输入n:”)的值;
int num=(console.readInt());
System.out.println(“\n最大的第n个斐波那契:“+fib(num));
System.out.println();
}
静态整数fib(整数n){
int f=0;
int g=1;
int-largeNum=-1;
对于(int i=0;i
不要传递索引,
n
,而是编写一个接受限制的函数,让它生成达到并包括该限制的斐波那契数。让它返回一个布尔值,这取决于它是否超出了限制,您可以使用它来检查该值是否在序列中


因为这是一个家庭作业,像这样的轻推可能是我们应该给你的全部…

如果我理解正确,你需要做的(而不是写出前n个斐波那契数)是确定n是否是斐波那契数

因此,您应该修改您的方法以继续生成斐波那契序列,直到得到一个大于等于n的数字。如果等于,n是斐波那契数,否则不是

更新:由于@Moron一再声称基于公式的算法在性能上优于上面简单的算法,我实际上做了一个基准比较——具体地说是Jacopo的解决方案作为生成器算法和StevenH的上一个版本作为基于公式的算法。以下是准确的代码供参考:

public static void main(String[] args) {
    measureExecutionTimeForGeneratorAlgorithm(1);
    measureExecutionTimeForFormulaAlgorithm(1);

    measureExecutionTimeForGeneratorAlgorithm(10);
    measureExecutionTimeForFormulaAlgorithm(10);

    measureExecutionTimeForGeneratorAlgorithm(100);
    measureExecutionTimeForFormulaAlgorithm(100);

    measureExecutionTimeForGeneratorAlgorithm(1000);
    measureExecutionTimeForFormulaAlgorithm(1000);

    measureExecutionTimeForGeneratorAlgorithm(10000);
    measureExecutionTimeForFormulaAlgorithm(10000);

    measureExecutionTimeForGeneratorAlgorithm(100000);
    measureExecutionTimeForFormulaAlgorithm(100000);

    measureExecutionTimeForGeneratorAlgorithm(1000000);
    measureExecutionTimeForFormulaAlgorithm(1000000);

    measureExecutionTimeForGeneratorAlgorithm(10000000);
    measureExecutionTimeForFormulaAlgorithm(10000000);

    measureExecutionTimeForGeneratorAlgorithm(100000000);
    measureExecutionTimeForFormulaAlgorithm(100000000);

    measureExecutionTimeForGeneratorAlgorithm(1000000000);
    measureExecutionTimeForFormulaAlgorithm(1000000000);

    measureExecutionTimeForGeneratorAlgorithm(2000000000);
    measureExecutionTimeForFormulaAlgorithm(2000000000);
}

static void measureExecutionTimeForGeneratorAlgorithm(int x) {
    final int count = 1000000;
    final long start = System.nanoTime();
    for (int i = 0; i < count; i++) {
        isFibByGeneration(x);
    }
    final double elapsedTimeInSec = (System.nanoTime() - start) * 1.0e-9;
    System.out.println("Running generator algorithm " + count + " times for " + x + " took " +elapsedTimeInSec + " seconds");
}

static void measureExecutionTimeForFormulaAlgorithm(int x) {
    final int count = 1000000;
    final long start = System.nanoTime();
    for (int i = 0; i < count; i++) {
        isFibByFormula(x);
    }
    final double elapsedTimeInSec = (System.nanoTime() - start) * 1.0e-9;
    System.out.println("Running formula algorithm " + count + " times for " + x + " took " +elapsedTimeInSec + " seconds");
}

static boolean isFibByGeneration(int x) {
    int a=0;
    int b=1;
    int f=1;
    while (b < x){
        f = a + b;
        a = b;
        b = f;
    }
    return x == f;
}

private static boolean isFibByFormula(int num) {
    double first = 5 * Math.pow((num), 2) + 4;
    double second = 5 * Math.pow((num), 2) - 4;

    return isWholeNumber(Math.sqrt(first)) || isWholeNumber(Math.sqrt(second));
}

private static boolean isWholeNumber(double num) {
    return num - Math.round(num) == 0;
}
简言之,生成器算法在所有正int值上都优于基于公式的解决方案-即使接近最大int值,其速度也要快两倍以上! 基于信念的性能优化到此为止;-)

对于记录,将上述代码修改为使用
long
变量而不是
int
,生成器算法会变慢(正如预期的那样,因为现在必须将
long
值相加),公式开始变快的转换点约为10000000000L,即1012

更新2:正如IVlad和Moron所指出的,我不是浮点计算方面的专家:-)根据他们的建议,我将公式改进为:

private static boolean isFibByFormula(long num)
{
    double power = (double)num * (double)num;
    double first = 5 * power + 4;
    double second = 5 * power - 4;

    return isWholeNumber(Math.sqrt(first)) || isWholeNumber(Math.sqrt(second));
}
这将切换点降低到大约108(对于
长版
版本-对于所有int值,带
int
的生成器速度更快)。毫无疑问,将
sqrt
调用替换为@Moron建议的调用将进一步降低转换点

我(和IVlad)的观点很简单,总是会有一个转换点,低于这个转换点,生成器算法会更快。因此,关于哪一种表现更好的说法在一般意义上没有意义,只是在某种背景下才有意义。

阅读上题为“识别斐波那契数”的章节

或者,正整数z是斐波那契数当且仅当5z^2+4或5z^2中的一个− 4是一个完美的正方形


或者,您可以继续生成斐波那契数,直到一个数等于您的数:如果它等于,则您的数是斐波那契数,否则,这些数最终将大于您的数,您可以停止。然而,这是相当低效的

正整数x是斐波那契数当且仅当5x^2+4和5x^2-4中的一个是一个完美的平方

我不知道是否有一个实际公式可以应用于用户输入。但是,您可以生成斐波那契序列,并对照用户输入检查它,直到它小于生成的最后一个数字

int userInput = n;
int a = 1, b = 1;

while (a < n) {
  if (a == n)
    return true;

  int next = a + b;
  b = a;
  a = next;
}

return false;
intuserinput=n;
INTA=1,b=1;
while(a
如果我的Java不是太生锈

static bool isFib(int x) {
    int a=0;
    int b=1;
    int f=1;
    while (b < x){
        f = a + b;
        a = b;
        b = f;
    }
    return x == f;
}
static bool isFib(int x){
int a=0;
int b=1;
int f=1;
while(b
为了充分利用您已经编写的代码,我首先提出以下建议,因为这是最简单的解决方案(但不是最有效的):


有很多方法可以用来确定给定的数字是否在斐波那契序列中,可以在上面看到一些选择

但是,考虑到您已经完成的工作,我可能会使用更为暴力的方法,例如:

  • 生成斐波那契数
  • 如果小于目标值,则生成下一个斐波那契并重复
  • 如果是目标号码,则成功
  • 如果大于目标值,则失败

  • 我可能会使用递归方法,传入当前的n值(即,它计算第n个斐波那契数)和目标数。

    可以用两种方法来实现,递归和数学方法。 递归方法 开始生成斐波那契序列,直到您找到或通过该数字 这里很好地描述了数学方法。。。


    祝你好运。

    好的。由于人们声称我只是空谈(“事实”与“猜测”),没有任何数据支持,我写了一个自己的基准

    不是java,而是下面的C代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace SO
    {
        class Program
        {
            static void Main(string[] args)
            {
                AssertIsFibSqrt(100000000);
    
                MeasureSequential(1);
                MeasureSqrt(1);
    
                MeasureSequential(10);
                MeasureSqrt(10);
    
                MeasureSequential(50);
                MeasureSqrt(50);
    
                MeasureSequential(100);
                MeasureSqrt(100);
    
    
                MeasureSequential(100000);
                MeasureSqrt(100000);
    
                MeasureSequential(100000000);
                MeasureSqrt(100000000);
    
            }
    
            static void MeasureSequential(long n)
            {
                int count = 1000000;
                DateTime start = DateTime.Now;
                for (int i = 0; i < count; i++)
                {
                    IsFibSequential(n);
                }
                DateTime end = DateTime.Now;
    
                TimeSpan duration = end - start;
    
                Console.WriteLine("Sequential for input = " + n + 
                                  " : " + duration.Ticks);
            }
    
            static void MeasureSqrt(long n)
            {
                int count = 1000000;
    
                DateTime start = DateTime.Now;
                for (int i = 0; i < count; i++)
                {
                    IsFibSqrt(n);
                }
                DateTime end = DateTime.Now;
    
                TimeSpan duration = end - start;
    
                Console.WriteLine("Sqrt for input =  " + n + 
                                  " : " + duration.Ticks);
            }
    
            static void AssertIsFibSqrt(long x)
            {
    
                Dictionary<long, bool> fibs = new Dictionary<long, bool>();
                long a = 0;
                long b = 1;
                long f = 1;
    
                while (b < x)
                {
                    f = a + b;
                    a = b;
                    b = f;
    
                    fibs[a] = true;
                    fibs[b] = true;
                }
    
                for (long i = 1; i <= x; i++)
                {
                    bool isFib = fibs.ContainsKey(i);
    
                    if (isFib && IsFibSqrt(i))
                    {
                        continue;
                    }
    
                    if (!isFib && !IsFibSqrt(i))
                    {
                        continue;
                    }
    
                    Console.WriteLine("Sqrt Fib test failed for: " + i);
                }
            }
            static bool IsFibSequential(long x)
            {
                long a = 0;
                long b = 1;
                long f = 1;
    
                while (b < x)
                {
                    f = a + b;
                    a = b;
                    b = f;
                }
                return x == f;
            }
    
            static bool IsFibSqrt(long x)
            {
                long y = 5 * x * x + 4;
    
                double doubleS = Math.Sqrt(y);
    
                long s = (long)doubleS;
    
                long sqr = s*s;
    
                return (sqr == y || sqr == (y-8));
            }
        }
    }
    
    当n=50时,sqrt方法本身就优于naive方法,这可能是因为我的机器上存在硬件支持。即使它是10^8(就像在彼得的测试中),在这个截止点下最多有40个斐波那契数,这可以很容易地放入查找中
    private static void main(string[] args)
    {
        //This will determnine which numbers between 1 & 100 are in the fibonacci series
        //you can swop in code to read from console rather than 'i' being used from the for loop
        for (int i = 0; i < 100; i++)
        {
            bool result = isFib(1);
    
            if (result)
                System.out.println(i + " is in the Fib series.");
    
            System.out.println(result);
        }
    
    }
    
    private static bool isFib(int num)
    {
        int counter = 0;
    
        while (true)
        {
            if (fib(counter) < num)
            {
                counter++;
                continue;
            }
    
            if (fib(counter) == num)
            {
                return true;
            }
    
            if (fib(counter) > num)
            {
                return false;
            }
        }
    }
    
    public static long fib(int n) 
    {
       if (n <= 1) 
          return n;
       else 
          return fib(n-1) + fib(n-2);
    }
    
    //(5z^2 + 4 or 5z^2 − 4) = a perfect square 
    //perfect square = an integer that is the square of an integer
    private static bool isFib(int num)
    {
        double first = 5 * Math.pow((num), 2) + 4;
        double second = 5 * Math.pow((num), 2) - 4;
    
        return isWholeNumber(Math.sqrt(first)) || isWholeNumber(Math.sqrt(second));
    }
    
    private static bool isWholeNumber(double num)
    {
        return num - Math.round(num) == 0;    
    }
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace SO
    {
        class Program
        {
            static void Main(string[] args)
            {
                AssertIsFibSqrt(100000000);
    
                MeasureSequential(1);
                MeasureSqrt(1);
    
                MeasureSequential(10);
                MeasureSqrt(10);
    
                MeasureSequential(50);
                MeasureSqrt(50);
    
                MeasureSequential(100);
                MeasureSqrt(100);
    
    
                MeasureSequential(100000);
                MeasureSqrt(100000);
    
                MeasureSequential(100000000);
                MeasureSqrt(100000000);
    
            }
    
            static void MeasureSequential(long n)
            {
                int count = 1000000;
                DateTime start = DateTime.Now;
                for (int i = 0; i < count; i++)
                {
                    IsFibSequential(n);
                }
                DateTime end = DateTime.Now;
    
                TimeSpan duration = end - start;
    
                Console.WriteLine("Sequential for input = " + n + 
                                  " : " + duration.Ticks);
            }
    
            static void MeasureSqrt(long n)
            {
                int count = 1000000;
    
                DateTime start = DateTime.Now;
                for (int i = 0; i < count; i++)
                {
                    IsFibSqrt(n);
                }
                DateTime end = DateTime.Now;
    
                TimeSpan duration = end - start;
    
                Console.WriteLine("Sqrt for input =  " + n + 
                                  " : " + duration.Ticks);
            }
    
            static void AssertIsFibSqrt(long x)
            {
    
                Dictionary<long, bool> fibs = new Dictionary<long, bool>();
                long a = 0;
                long b = 1;
                long f = 1;
    
                while (b < x)
                {
                    f = a + b;
                    a = b;
                    b = f;
    
                    fibs[a] = true;
                    fibs[b] = true;
                }
    
                for (long i = 1; i <= x; i++)
                {
                    bool isFib = fibs.ContainsKey(i);
    
                    if (isFib && IsFibSqrt(i))
                    {
                        continue;
                    }
    
                    if (!isFib && !IsFibSqrt(i))
                    {
                        continue;
                    }
    
                    Console.WriteLine("Sqrt Fib test failed for: " + i);
                }
            }
            static bool IsFibSequential(long x)
            {
                long a = 0;
                long b = 1;
                long f = 1;
    
                while (b < x)
                {
                    f = a + b;
                    a = b;
                    b = f;
                }
                return x == f;
            }
    
            static bool IsFibSqrt(long x)
            {
                long y = 5 * x * x + 4;
    
                double doubleS = Math.Sqrt(y);
    
                long s = (long)doubleS;
    
                long sqr = s*s;
    
                return (sqr == y || sqr == (y-8));
            }
        }
    }
    
    Sequential for input = 1 : 110011
    Sqrt for input =  1 : 670067
    
    Sequential for input = 10 : 560056
    Sqrt for input =  10 : 540054
    
    Sequential for input = 50 : 610061
    Sqrt for input =  50 : 540054
    
    Sequential for input = 100 : 730073
    Sqrt for input =  100 : 540054
    
    Sequential for input = 100000 : 1490149
    Sqrt for input =  100000 : 540054
    
    Sequential for input = 100000000 : 2180218
    Sqrt for input =  100000000 : 540054
    
    //Program begins
    
    
    public class isANumberFibonacci {
    
        public static int fibonacci(int seriesLength) {
            if (seriesLength == 1 || seriesLength == 2) {
                return 1;
            } else {
                return fibonacci(seriesLength - 1) + fibonacci(seriesLength - 2);
            }
        }
    
        public static void main(String args[]) {
            int number = 4101;
            int i = 1;
            while (i > 0) {
                int fibnumber = fibonacci(i);
                if (fibnumber != number) {
                    if (fibnumber > number) {
                        System.out.println("Not fib");
                        break;
                    } else {
                        i++;
                    }
                } else {
                    System.out.println("The number is fibonacci");
                    break;
                }
            }
        }
    }
    
    //Program ends
    
    public static boolean isNumberFromFibonacciSequence(int num){
    
        if (num == 0 || num == 1){
            return true;
        }
    
        else {
            //5n^2 - 4 OR 5n^2 + 4 should be perfect squares
            return isPerfectSquare( 5*num*num - 4) || isPerfectSquare(5*num*num - 4);
        }
    }
    
    private static boolean isPerfectSquare(int num){
            double sqrt = Math.sqrt(num);
            return sqrt * sqrt == num;
    }
    
    public static int isFibonacci (int n){
      int isFib = 0;
      int a = 0, b = 0, c = a + b; // set up the initial values
      do 
       {
        a = b;
        b = c;
        c = a + b;
        if (c == n)
        isFib = 1;
        } while (c<=n && isFin == 0)
      return isFib;
    }
    
    public static void main(String [] args){
      System.out.println(isFibonacci(89));
    }