Determining whether a number is a Fibonacci number

前端 未结 14 1209
暗喜
暗喜 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:31

    If I understand correctly, what you need to do (instead of writing out the first n Fibonacci numbers) is to determine whether n is a Fibonacci number.

    So you should modify your method to keep generating the Fibonacci sequence until you get a number >= n. If it equals, n is a Fibonacci number, otherwise not.

    Update: bugged by @Moron's repeated claims about the formula based algorithm being superior in performance to the simple one above, I actually did a benchmark comparison - concretely between Jacopo's solution as generator algorithm and StevenH's last version as formula based algorithm. For reference, here is the exact code:

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

    The results surprised even me:

    Running generator algorithm 1000000 times for 1 took 0.007173537000000001 seconds
    Running formula algorithm 1000000 times for 1 took 0.223365539 seconds
    Running generator algorithm 1000000 times for 10 took 0.017330694 seconds
    Running formula algorithm 1000000 times for 10 took 0.279445852 seconds
    Running generator algorithm 1000000 times for 100 took 0.030283179 seconds
    Running formula algorithm 1000000 times for 100 took 0.27773557800000004 seconds
    Running generator algorithm 1000000 times for 1000 took 0.041044322 seconds
    Running formula algorithm 1000000 times for 1000 took 0.277931134 seconds
    Running generator algorithm 1000000 times for 10000 took 0.051103143000000004 seconds
    Running formula algorithm 1000000 times for 10000 took 0.276980175 seconds
    Running generator algorithm 1000000 times for 100000 took 0.062019335 seconds
    Running formula algorithm 1000000 times for 100000 took 0.276227007 seconds
    Running generator algorithm 1000000 times for 1000000 took 0.07422898800000001 seconds
    Running formula algorithm 1000000 times for 1000000 took 0.275485013 seconds
    Running generator algorithm 1000000 times for 10000000 took 0.085803922 seconds
    Running formula algorithm 1000000 times for 10000000 took 0.27701090500000003 seconds
    Running generator algorithm 1000000 times for 100000000 took 0.09543419600000001 seconds
    Running formula algorithm 1000000 times for 100000000 took 0.274908403 seconds
    Running generator algorithm 1000000 times for 1000000000 took 0.10683704200000001 seconds
    Running formula algorithm 1000000 times for 1000000000 took 0.27524084800000004 seconds
    Running generator algorithm 1000000 times for 2000000000 took 0.13019867100000002 seconds
    Running formula algorithm 1000000 times for 2000000000 took 0.274846384 seconds
    

    In short, the generator algorithm way outperforms the formula based solution on all positive int values - even close to the maximum int value it is more than twice as fast! So much for belief based performance optimization ;-)

    For the record, modifying the above code to use long variables instead of int, the generator algorithm becomes slower (as expected, since it has to add up long values now), and cutover point where the formula starts to be faster is around 1000000000000L, i.e. 1012.

    Update2: As IVlad and Moron noted, I am not quite an expert in floating point calculations :-) based on their suggestions I improved the formula to this:

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

    This brought down the cutover point to approx. 108 (for the long version - the generator with int is still faster for all int values). No doubt that replacing the sqrt calls with something like suggested by @Moron would push down the cutover point further.

    My (and IVlad's) point was simply that there will always be a cutover point, below which the generator algorithm is faster. So claims about which one performs better have no meaning in general, only in a context.

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

    A positive integer x is a Fibonacci number if and only if one of 5x^2 + 4 and 5x^2 - 4 is a perfect square

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

    Consider the sequence of Fibonacci numbers 1,1,2,3,5,8,13,21, etc. It is desired to build 3 stacks each of capacity 10 containing numbers from the above sequences as follows:

    Stack 1: First 10 numbers from the sequence. Stack 2: First 10 prime numbers from the sequence. Stack 3: First 10 non-prime numbers from the sequence.

    (i) Give an algorithm of the flowchart (ii) Write a program (in BASIC, C++ or Java) to implement this.

    Output:As stack operations take place you should display in any convenient form the 3 stacks together with the values held in them.

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

    Read the section titled "recognizing fibonacci numbers" on wikipedia.

    Alternatively, a positive integer z is a Fibonacci number if and only if one of 5z^2 + 4 or 5z^2 − 4 is a perfect square.[17]

    Alternatively, you can keep generating fibonacci numbers until one becomes equal to your number: if it does, then your number is a fibonacci number, if not, the numbers will eventually become bigger than your number, and you can stop. This is pretty inefficient however.

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

    Thought it was simple until i had to rack my head on it a few minutes. Its quite different from generating a fibonacci sequence. This function returns 1 if is Fibonnaci or 0 if not

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

    If my Java is not too rusty...

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