Determining whether a number is a Fibonacci number

前端 未结 14 1200
暗喜
暗喜 2021-01-18 05:35

I need to to write a Java code that checks whether the user inputed number is in the Fibonacci sequence.

I have no issue writing the Fibonacci sequence to output, b

相关标签:
14条回答
  • 2021-01-18 06:17
    //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
    
    0 讨论(0)
  • 2021-01-18 06:19

    There are a number of methods that can be employed to determine if a given number is in the fibonacci sequence, a selection of which can be seen on wikipedia.

    Given what you've done already, however, I'd probably use a more brute-force approach, such as the following:

    1. Generate a fibonacci number
    2. If it's less than the target number, generate the next fibonacci and repeat
    3. If it is the target number, then success
    4. If it's bigger than the target number, then failure.

    I'd probably use a recursive method, passing in a current n-value (ie. so it calculates the nth fibonacci number) and the target number.

    0 讨论(0)
  • 2021-01-18 06:23

    Ok. Since people claimed I am just talking thin air ('facts' vs 'guesses') without any data to back it up, I wrote a benchmark of my own.

    Not java, but C# code below.

    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));
            }
        }
    }
    

    And here is the output

    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
    

    The sqrt method beats the naive method when n=50 itself, perhaps due to the presence of hardware support on my machine. Even if it was 10^8 (like in Peter's test), there are at most 40 fibonacci numbers under that cutoff, which could easily be put in a lookup table and still beat the naive version for the smaller values.

    Also, Peter has a bad implementation of the SqrtVersion. He doesn't really need to compute two square roots or compute powers using Math.Pow. He could have atleast tried to make that better before publishing his benchmark results.

    Anyway, I will let these facts speak for themselves, instead of the so called 'guesses'.

    0 讨论(0)
  • 2021-01-18 06:25

    You can do this in two ways , the recursive and mathematical. the recursive way start generating fibonacci sequence until you hit the number or pass it the mathematical way nicely described here ... http://www.physicsforums.com/showthread.php?t=252798

    good luck.

    0 讨论(0)
  • 2021-01-18 06:27

    I don't know if there is an actual formula that you can apply to the user input however, you can generate the fibonacci sequence and check it against the user input until it has become smaller than the last number generated.

    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;
    
    0 讨论(0)
  • 2021-01-18 06:27

    Finding out whether a number is Fibonacci based on formula:

    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;
    }
    
    0 讨论(0)
提交回复
热议问题