जावा पुनरावर्ती फाइबोनैचि अनुक्रम


156

कृपया इस सरल कोड की व्याख्या करें:

public int fibonacci(int n)  {
    if(n == 0)
        return 0;
    else if(n == 1)
      return 1;
   else
      return fibonacci(n - 1) + fibonacci(n - 2);
}

मैं विशेष रूप से अंतिम पंक्ति में उलझन में हूं क्योंकि यदि उदाहरण के लिए n = 5 है, तो रिट्रेसमेंट (4) + रिट्रेसमेंट (3) कहा जाएगा और इसी तरह, लेकिन मुझे समझ में नहीं आता है कि यह एल्गोरिथ्म इसके द्वारा सूचकांक 5 पर मूल्य की गणना कैसे करता है तरीका। कृपया विस्तार से बताएं!


8
ध्यान दें कि यह पुनरावर्ती है और घातीय समय में चलता है। यह एन के बड़े मूल्यों के लिए अक्षम है। पुनरावृत्ति दृष्टिकोण का उपयोग करके मैं अनुक्रम में पहले 10,000 संख्याओं की गणना करने में सक्षम था। उन्हें यहां पाया जा सकता है - goo.gl/hnbF5
एडम

@AdamFisher: क्या आप अनुक्रम में 10,000 नंबरों की गणना के लिए उपयोग किए गए कोड को साझा कर सकते हैं? मैं वास्तव में इसे जानने के लिए उत्सुक हूं।
शुमैल

4
@AdamFisher आपके द्वारा संदर्भित लिंक मृत है।
22

2
यह वीडियो 10 minuts youtube.com/watch?v=t4MSwiqfLaY
समझाएगा

2
एक Iterative दृष्टिकोण भी है जो आपके लिए कम कठिन हो सकता है। यहाँ कोड के साथ पुनरावर्ती और Iterative दोनों पर महान लेख - codeflex.co/java-get-fibnote-number-by-index
user5495300

जवाबों:


165

रिट्रेसमेंट अनुक्रम में प्रत्येक आइटम पिछले दो का योग है। तो, आपने एक पुनरावर्ती एल्गोरिदम लिखा।

इसलिए,

fibonacci(5) = fibonacci(4) + fibonacci(3)

fibonacci(3) = fibonacci(2) + fibonacci(1)

fibonacci(4) = fibonacci(3) + fibonacci(2)

fibonacci(2) = fibonacci(1) + fibonacci(0)

अब आप पहले से ही जानते हैं fibonacci(1)==1 and fibonacci(0) == 0। तो, आप बाद में अन्य मानों की गणना कर सकते हैं।

अभी,

fibonacci(2) = 1+0 = 1
fibonacci(3) = 1+1 = 2
fibonacci(4) = 2+1 = 3
fibonacci(5) = 3+2 = 5

और फ़्रीक्वेंसी अनुक्रम से 0,1,1,2,3,5,8,13,21....हम देख सकते हैं कि 5th elementफ़्रीक्वेंसी अनुक्रम रिटर्न के लिए 5

पुनरावर्तन ट्यूटोरियल के लिए यहां देखें ।


यह काम करेगा लेकिन तब तक नहीं जब तक कि यह अनुकूलित न हो जाए। कृपया मेरे जवाब पर एक नज़र डालें। मुझे सुझाव / टिप्पणियों के मामले में बताएं
M Sach

52

आपके कोड के साथ 2 समस्याएँ हैं:

  1. परिणाम int में संग्रहीत किया जाता है जो केवल पहले 48 रिट्रेसमेंट नंबर को संभाल सकता है, इसके बाद पूर्णांक माइनस बिट भरता है और परिणाम गलत होता है।
  2. लेकिन आप कभी भी रिट्रेसमेंट (50) नहीं चला सकते हैं।
    कोड
    fibonacci(n - 1) + fibonacci(n - 2)
    बहुत गलत है।
    समस्या यह है कि यह 50 बार नहीं बल्कि बहुत अधिक रिट्रेसमेंट को कॉल करता है।
    सबसे पहले इसे रिट्रेसमेंट (49) + रिट्रेसमेंट (48),
    नेक्स्ट रिट्रेसमेंट (48) + रिट्रेसमेंट (47) और रिट्रेसमेंट (47) + रिट्रेसमेंट (46) कहते हैं कि
    हर बार यह रिट्रेसमेंट (एन) बदतर हो जाता है, इसलिए जटिलता एक्सपोनेंशियल है। यहां छवि विवरण दर्ज करें

गैर-पुनरावर्ती कोड के लिए दृष्टिकोण:

 double fibbonaci(int n){
    double prev=0d, next=1d, result=0d;
    for (int i = 0; i < n; i++) {
        result=prev+next;
        prev=next;
        next=result;
    }
    return result;
}

4
यद्यपि कुछ अन्य उत्तर पुनरावृत्ति को अधिक स्पष्ट रूप से समझाते हैं, यह संभवतः गहरे स्तर पर सबसे अधिक प्रासंगिक उत्तर है।
हेल ​​50000

1
"पूर्णांक शून्य से थोड़ा सा भरें" का क्या अर्थ है?
रिकर्ड

1
@richard, यह इस बारे में है कि पूर्णांक कैसे संग्रहीत किया जाता है। Int 2 ^ 31-1 पर पहुंचने के बाद अगला बिट साइन के बारे में है, इसलिए संख्या नकारात्मक हो जाती है।
5

बहुत तेज तो पुनरावर्ती। एकमात्र आरक्षण यह है कि यह n = 1 के लिए काम नहीं करेगा। अतिरिक्त स्थिति की आवश्यकता है
v0rin

1
"हर बार यह 2 ^ n बदतर हो गया" वास्तव में कुल फ़ंक्शन कॉल की संख्या है 2*fibonacci(n+1)-1, इसलिए यह उसी जटिलता के साथ बढ़ता है, जो स्वयं की संख्याओं की संख्या है, जो 2 ^ n के बजाय 1.618 ^ n है
Aemyl

37

छद्म कोड में, जहां n = 5, निम्नलिखित जगह लेता है:

रिट्रेसमेंट (4) + फाइबॉनेसिया (3)

इसमें टूट जाता है:

(रिट्रेसमेंट (3) + फाइबॉन्शस (2)) + (रिटायरमेंट्स (2) + फाइबॉनेसिया (1))

इसमें टूट जाता है:

((रिट्रेसमेंट (2) + फ़ाइबॉन्शिक (1)) + (((1 (+) + फ़ाइबोनैचि (0))) ((((1 (+) + फ़ाइबोनैचि (0)) + 1)

इसमें टूट जाता है:

(((((1 (+ 1) + फ़ाइबॉन्शिक) + 1) + ((1 + 0)) + ((1 + 0) + 1)

इसमें टूट जाता है:

((((1 + 0) + 1) + (((1 + 0)) + ((1 + 0) + 1)

यह परिणाम है: 5

फाइबोनेकिया अनुक्रम को देखते हुए 1 1 2 3 5 8 ... , 5 वां तत्व 5. आप अन्य पुनरावृत्तियों का पता लगाने के लिए उसी पद्धति का उपयोग कर सकते हैं।


मुझे लगता है कि यह उत्तर प्रश्नों को सबसे अच्छा तरीका बताता है। वास्तव में सरल
अमित

यह साफ-सुथरा है। एनएचटी अवधि और इसके बाद की श्रृंखला में दोनों मूल्य बताते हैं।
अर्धविराम

12

पुनरावृत्ति कभी-कभी समझ में आना मुश्किल हो सकती है। बस एक छोटी संख्या के लिए कागज के टुकड़े पर इसका मूल्यांकन करें:

fib(4)
-> fib(3) + fib(2)
-> fib(2) + fib(1) + fib(1) + fib(0)
-> fib(1) + fib(0) + fib(1) + fib(1) + fib(0)
-> 1 + 0 + 1 + 1 + 0
-> 3

मुझे यकीन नहीं है कि जावा वास्तव में इसका मूल्यांकन कैसे करता है, लेकिन परिणाम समान होगा।


दूसरी पंक्ति पर अंत में 1 और 0 कहाँ से आता है?
pocockn

1
@ पॉकॉकन फ़ाइब (2) = फ़ाइब (1) + फ़ाइब (0)
टिम

तो आपके पास फ़ाइब (4) है तो n-1 और n-2 फ़ाइबर (3) + फ़ाइबर (2) होगा तो आप n-1 और n-2 करें फिर से आप प्राप्त करें -> फ़ाइबर (2) + फ़ाइबर (1) ), आपको + फ़ाइबर (1) + फ़ाइबर (0) कहाँ से मिला है? अंत पर जोड़ा
pocockn

@ पोकॉकन फ़ाइब (2) + फ़ाइब (1) फ़ाइब (3), फ़ाइबर (1) + फ़ाइब (0) फ़ाइब (2) से है
टिम

12

आप अपने कार्य को सरल बना सकते हैं, इस प्रकार है:

public int fibonacci(int n)  {
    if (n < 2) return n;

    return fibonacci(n - 1) + fibonacci(n - 2);
}

यह इस या इस या इस उत्तर से अलग कैसे है ?
21:39 पर तुनकी

6
यह सिर्फ पढ़ने में आसान और आसान है, जो एल्गोरिदम हमेशा होना चाहिए =)
ओटावियो फरेरा

@OtavioFerreira एकमात्र जवाब जो मेरी समस्या को सुलझाने में कामयाब रहा, अच्छी नौकरी
KKKKK

8
                                F(n)
                                /    \
                            F(n-1)   F(n-2)
                            /   \     /      \
                        F(n-2) F(n-3) F(n-3)  F(n-4)
                       /    \
                     F(n-3) F(n-4)

नोट करने के लिए महत्वपूर्ण बिंदु यह एल्गोरिथ्म घातीय है क्योंकि यह पिछले गणना की गई संख्या के परिणाम को संग्रहीत नहीं करता है। उदाहरण के लिए F (n-3) को 3 बार कहा जाता है।

अधिक जानकारी के लिए दासगुप्त अध्याय 0.2 द्वारा एल्गोरिथ्म देखें


एक प्रोग्रामिंग कार्यप्रणाली है जिसके द्वारा हम एक ही n के लिए F (n) की गणना करने से बार-बार डायनेमिक प्रोग्रामिंग का उपयोग कर सकते हैं
अमित_होरा

8

अधिकांश उत्तर अच्छे हैं और बताते हैं कि कैसे काम करता है।

यहाँ तीन तकनीकों पर एक विश्लेषण है जिसमें पुनरावृत्ति भी शामिल है:

  1. पाश के लिए
  2. प्रत्यावर्तन
  3. Memoization

यहाँ तीनों का परीक्षण करने के लिए मेरा कोड है:

public class Fibonnaci {
    // Output = 0 1 1 2 3 5 8 13

    static int fibMemo[];

    public static void main(String args[]) {
        int num = 20;

        System.out.println("By For Loop");
        Long startTimeForLoop = System.nanoTime();
        // returns the fib series
        int fibSeries[] = fib(num);
        for (int i = 0; i < fibSeries.length; i++) {
            System.out.print(" " + fibSeries[i] + " ");
        }
        Long stopTimeForLoop = System.nanoTime();
        System.out.println("");
        System.out.println("For Loop Time:" + (stopTimeForLoop - startTimeForLoop));


        System.out.println("By Using Recursion");
        Long startTimeRecursion = System.nanoTime();
        // uses recursion
        int fibSeriesRec[] = fibByRec(num);

        for (int i = 0; i < fibSeriesRec.length; i++) {
            System.out.print(" " + fibSeriesRec[i] + " ");
        }
        Long stopTimeRecursion = System.nanoTime();
        System.out.println("");
        System.out.println("Recursion Time:" + (stopTimeRecursion -startTimeRecursion));



        System.out.println("By Using Memoization Technique");
        Long startTimeMemo = System.nanoTime();
        // uses memoization
        fibMemo = new int[num];
        fibByRecMemo(num-1);
        for (int i = 0; i < fibMemo.length; i++) {
            System.out.print(" " + fibMemo[i] + " ");
        }
        Long stopTimeMemo = System.nanoTime();
        System.out.println("");
        System.out.println("Memoization Time:" + (stopTimeMemo - startTimeMemo));

    }


    //fib by memoization

    public static int fibByRecMemo(int num){

        if(num == 0){
            fibMemo[0] = 0;
            return 0;
        }

        if(num ==1 || num ==2){
          fibMemo[num] = 1;
          return 1; 
        }

        if(fibMemo[num] == 0){
            fibMemo[num] = fibByRecMemo(num-1) + fibByRecMemo(num -2);
            return fibMemo[num];
        }else{
            return fibMemo[num];
        }

    }


    public static int[] fibByRec(int num) {
        int fib[] = new int[num];

        for (int i = 0; i < num; i++) {
            fib[i] = fibRec(i);
        }

        return fib;
    }

    public static int fibRec(int num) {
        if (num == 0) {
            return 0;
        } else if (num == 1 || num == 2) {
            return 1;
        } else {
            return fibRec(num - 1) + fibRec(num - 2);
        }
    }

    public static int[] fib(int num) {
        int fibSum[] = new int[num];
        for (int i = 0; i < num; i++) {
            if (i == 0) {
                fibSum[i] = i;
                continue;
            }

            if (i == 1 || i == 2) {
                fibSum[i] = 1;
                continue;
            }

            fibSum[i] = fibSum[i - 1] + fibSum[i - 2];

        }
        return fibSum;
    }

}

यहाँ परिणाम हैं:

By For Loop
 0  1  1  2  3  5  8  13  21  34  55  89  144  233  377  610  987  1597  2584  4181 
For Loop Time:347688
By Using Recursion
 0  1  1  2  3  5  8  13  21  34  55  89  144  233  377  610  987  1597  2584  4181 
Recursion Time:767004
By Using Memoization Technique
 0  1  1  2  3  5  8  13  21  34  55  89  144  233  377  610  987  1597  2584  4181 
Memoization Time:327031

इसलिए हम देख सकते हैं कि संस्मरण सबसे अच्छा समय है और लूप मैचों के लिए निकटता से है।

लेकिन पुनरावृत्ति सबसे लंबे समय तक होती है और हो सकता है कि आपको वास्तविक जीवन में बचना चाहिए। इसके अलावा यदि आप पुनरावृत्ति का उपयोग कर रहे हैं, तो सुनिश्चित करें कि आप समाधान का अनुकूलन करते हैं।


1
"यहां हम लूप के लिए देख सकते हैं सबसे अच्छा समय है"; "लूप टाइम के लिए: 347688"; "संस्मरण समय: 327031"; 347688> 327031.
अजाहर्नहेल्स

@CodeConfident हाँ, मैंने आज उस गलती को देखा और उसे सही करने वाला था। फिर भी धन्यवाद :)।
प्रीतम बनर्जी

7

यह सबसे अच्छा वीडियो है जो मैंने पाया है कि जावा में पूरी तरह से पुनरावृत्ति और फाइबोनैचि अनुक्रम की व्याख्या करता है।

http://www.youtube.com/watch?v=dsmBRUCzS7k

यह अनुक्रम के लिए उनका कोड है और उनका स्पष्टीकरण इससे बेहतर है कि मैं इसे टाइप करने की कोशिश कर सकता हूं।

public static void main(String[] args)
{
    int index = 0;
    while (true)
    {
        System.out.println(fibonacci(index));
        index++;
    }
}
    public static long fibonacci (int i)
    {
        if (i == 0) return 0;
        if (i<= 2) return 1;

        long fibTerm = fibonacci(i - 1) + fibonacci(i - 2);
        return fibTerm;
    }

5

रिट्रेसर्स रिकर्सिव सॉल्यूशन के लिए, बड़ी संख्या के मूल्य को पुनः प्राप्त करते हुए, छोटे रिट्रेसमेंट नंबरों के आउटपुट को बचाना महत्वपूर्ण है। इसे "मेमोइज़िंग" कहा जाता है।

यहाँ एक कोड है जो छोटे रिट्रेसमेंट मानों को याद रखने का उपयोग करता है, जबकि बड़ी रिट्रेसमेंट संख्या को पुनः प्राप्त करता है। यह कोड कुशल है और एक ही फ़ंक्शन के कई अनुरोध नहीं करता है।

import java.util.HashMap;

public class Fibonacci {
  private HashMap<Integer, Integer> map;
  public Fibonacci() {
    map = new HashMap<>();
  }
  public int findFibonacciValue(int number) {
    if (number == 0 || number == 1) {
      return number;
    }
    else if (map.containsKey(number)) {
      return map.get(number);
    }
    else {
      int fibonacciValue = findFibonacciValue(number - 2) + findFibonacciValue(number - 1);
      map.put(number, fibonacciValue);
      return fibonacciValue;
    }
  }
}

4

में फिबोनैकी अनुक्रम, पहले दो आइटम 0 और 1 हैं, एक-दूसरे मद पिछले दो आइटम का योग है। अर्थात:
0 1 1 2 3 5 8 ...

इसलिए 5 वाँ आइटम 4 और 3 आइटम का योग है।


4

माइकल गुडरिक एट अल डेटा संरचनाओं और जावा में एल्गोरिदम में एक बहुत ही चतुर एल्गोरिथ्म प्रदान करता है, [फाइबर्स (n), फ़ाइबर (एन -1)] की एक सरणी लौटाकर रेखीय समय में रिटर्न्स को हल करने के लिए।

public static long[] fibGood(int n) {
    if (n < = 1) {
        long[] answer = {n,0};
        return answer;
    } else {
        long[] tmp = fibGood(n-1);
        long[] answer = {tmp[0] + tmp[1], tmp[0]};
        return answer;
    }
}

यह पैदावार फ़ाइब (n) = फ़ाइबगूड (n) [को ०]।


4

यहाँ हे (1) समाधान है:

 private static long fibonacci(int n) {
    double pha = pow(1 + sqrt(5), n);
    double phb = pow(1 - sqrt(5), n);
    double div = pow(2, n) * sqrt(5);

    return (long) ((pha - phb) / div);
}

उपरोक्त कार्यान्वयन के लिए बिनेट के फाइबोनैचि संख्या सूत्र का उपयोग किया जाता है। बड़े आदानों के longसाथ प्रतिस्थापित किया जा सकता है BigDecimal


3

एक Fibbonacci अनुक्रम वह संख्या है जो किसी संख्या के परिणाम को तब जोड़ती है जब पिछले परिणाम को 1 से शुरू किया जाता है।

      so.. 1 + 1 = 2
           2 + 3 = 5
           3 + 5 = 8
           5 + 8 = 13
           8 + 13 = 21

एक बार जब हम समझते हैं कि फाइबोनकेशिया क्या है, तो हम कोड को तोड़ना शुरू कर सकते हैं।

public int fibonacci(int n)  {
    if(n == 0)
        return 0;
    else if(n == 1)
      return 1;
   else
      return fibonacci(n - 1) + fibonacci(n - 2);
}

यदि आधार बेस केस के लिए स्टेटमेंट चेक करता है तो पहला, जहां लूप टूट सकता है। और अगर नीचे दिया गया कथन समान है, लेकिन ऐसा फिर से लिखा जा सकता है ...

    public int fibonacci(int n)  {
        if(n < 2)
             return n;

        return fibonacci(n - 1) + fibonacci(n - 2);
    }

अब जब एक आधार मामला स्थापित हो गया है तो हमें कॉल स्टैक को समझना होगा। आपका पहला कॉल "रिट्रेसमेंट" स्टैक (कॉल का अनुक्रम) पर हल करने के लिए अंतिम होगा क्योंकि वे रिवर्स ऑर्डर में हल करते हैं जिसमें से उन्हें बुलाया गया था। अंतिम विधि को पहले हल किया जाता है, फिर आखिरी को उस से पहले बुलाया जाता है ...

इसलिए, उन परिणामों के साथ कुछ भी "गणना" करने से पहले सभी कॉल पहले किए जाते हैं। 8 के इनपुट के साथ हम 21 के आउटपुट की उम्मीद करते हैं (ऊपर दी गई तालिका देखें)।

रिट्रेसमेंट (n - 1) को तब तक बुलाया जाता है जब तक कि यह बेस केस तक नहीं पहुंच जाता है, तब बेस केस तक पहुंचने तक रिट्रेसमेंट (n - 2) कहा जाता है। जब स्टैक परिणाम को रिवर्स ऑर्डर में समेटना शुरू करता है, तो परिणाम ऐसा होगा ...

1 + 1 = 1        ---- last call of the stack (hits a base case).
2 + 1 = 3        ---- Next level of the stack (resolving backwards).
2 + 3 = 5        ---- Next level of the stack (continuing to resolve).

वे तब तक बुदबुदाते रहते हैं (पीछे की ओर बढ़ते हुए) जब तक कि सही राशि स्टैक में पहली कॉल पर वापस नहीं आ जाती है और इस तरह से आपको अपना उत्तर मिल जाता है।

यह कहते हुए कि, यह एल्गोरिथ्म बहुत अक्षम है क्योंकि यह प्रत्येक शाखा के लिए समान परिणाम की गणना करता है जिसमें कोड विभाजित होता है। बहुत बेहतर दृष्टिकोण एक "बॉटम अप" है जहां कोई मेमोइज़ेशन (कैशिंग) या पुनरावृत्ति (गहरी कॉल स्टैक) की आवश्यकता नहीं है।

इस तरह...

        static int BottomUpFib(int current)
        {
            if (current < 2) return current;

            int fib = 1;
            int last = 1;

            for (int i = 2; i < current; i++)
            {
                int temp = fib;
                fib += last;
                last = temp;
            }

            return fib;
        }

2

यहाँ दिए गए अधिकांश समाधान O (2 ^ n) जटिलता में चलते हैं। पुनरावर्ती पेड़ में समान नोड्स को पुनर्गणना करना अक्षम है और सीपीयू चक्रों को बर्बाद करता है।

हम ओ (एन) समय में फंक्शंस को फॉलो करने के लिए मेमोनाइजेशन का उपयोग कर सकते हैं

public static int fibonacci(int n) {
    return fibonacci(n, new int[n + 1]);
}

public static int fibonacci(int i, int[] memo) {

    if (i == 0 || i == 1) {
        return i;
    }

    if (memo[i] == 0) {
        memo[i] = fibonacci(i - 1, memo) + fibonacci(i - 2, memo);
    }
    return memo[i];
}

यदि हम बॉटम-अप डायनेमिक प्रोग्रामिंग रूट का अनुसरण करते हैं, तो नीचे दिए गए कोड, कॉम्पिटिटर की गणना करने के लिए पर्याप्त सरल हैं:

public static int fibonacci1(int n) {
    if (n == 0) {
        return n;
    } else if (n == 1) {
        return n;
    }
    final int[] memo = new int[n];

    memo[0] = 0;
    memo[1] = 1;

    for (int i = 2; i < n; i++) {
        memo[i] = memo[i - 1] + memo[i - 2];
    }
    return memo[n - 1] + memo[n - 2];
}

2

यह उत्तर अलग क्यों है

हर दूसरे जवाब या तो:

  • रिटर्न के बजाय प्रिंट
  • प्रति पुनरावृत्ति 2 पुनरावर्ती कॉल करता है
  • लूप का उपयोग करके प्रश्न को अनदेखा करता है

(एक तरफ: इनमें से कोई भी वास्तव में कुशल नहीं है; सीधे वें n शब्द की गणना के लिए Binet के सूत्र का उपयोग करें )

पूंछ पुनरावर्ती तंतु

यहां एक पुनरावर्ती दृष्टिकोण है जो पिछले उत्तर और उससे पहले दोनों को पास करके एक दोहराव-पुनरावर्ती कॉल से बचा जाता है।

private static final int FIB_0 = 0;
private static final int FIB_1 = 1;

private int calcFibonacci(final int target) {
    if (target == 0) { return FIB_0; }
    if (target == 1) { return FIB_1; }

    return calcFibonacci(target, 1, FIB_1, FIB_0);
}

private int calcFibonacci(final int target, final int previous, final int fibPrevious, final int fibPreviousMinusOne) {
    final int current = previous + 1;
    final int fibCurrent = fibPrevious + fibPreviousMinusOne;
    // If you want, print here / memoize for future calls

    if (target == current) { return fibCurrent; }

    return calcFibonacci(target, current, fibCurrent, fibPrevious);
}

1

यह एक मूल अनुक्रम है जो 1 1 2 3 5 8 का आउटपुट प्रदर्शित करता है या प्राप्त करता है यह एक अनुक्रम है कि पिछली संख्या का योग वर्तमान संख्या को प्रदर्शित करेगा।

जावा पुनरावर्ती फाइबोनैचि अनुक्रम ट्यूटोरियल के नीचे लिंक देखने का प्रयास करें

public static long getFibonacci(int number){
if(number<=1) return number;
else return getFibonacci(number-1) + getFibonacci(number-2);
}

चम्मच खाने के लिए यहाँ क्लिक करें जावा पुनरावर्ती फाइबोनैचि अनुक्रम ट्यूटोरियल देखें


उसे यह समझने की जरूरत है कि कोड कैसे काम करता है और यह क्यों लिखा जाता है, जिस तरह से इसे लिखा जाता है।
आदर्श

मुझे लगता है कि मैं अपने पहले वाक्य में उल्लेख करता हूं कि यह कैसे काम करता है? मैं इसे और अधिक सरल बनाने के लिए कोड लिखता हूं। btw, क्षमा करें।
Jaymelson Galang

आपके कोड में कुछ भी गलत नहीं है। केवल आदमी समझना चाहता था कि उस कोड ने कैसे काम किया। RanRag द्वारा उत्तर की जाँच करें। उस तरह :) के बारे में कुछ
आदर्श

आह ठीक है, माफ करना, मैं यहां स्टैकओवरफ्लो में शुरुआत कर रहा हूं। बस मदद करना चाहते हैं ^ _ ^
Jaymelson Galang

1

मुझे लगता है कि यह एक सरल तरीका है:

public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int number = input.nextInt();
        long a = 0;
        long b = 1;
        for(int i = 1; i<number;i++){
            long c = a +b;
            a=b;
            b=c;
            System.out.println(c);
        }
    }
}

1

RanRag (स्वीकृत) उत्तर ठीक काम करेगा, लेकिन जब तक इसे अनिल उत्तर में स्पष्ट नहीं किया जाता है, तब तक अनुकूलित समाधान नहीं होता है।

नीचे दिए गए दृष्टिकोण पर पुनरावर्ती विचार के लिए, विधि कॉल TestFibonacciन्यूनतम हैं

public class TestFibonacci {

    public static void main(String[] args) {

        int n = 10;

        if (n == 1) {
            System.out.println(1);

        } else if (n == 2) {
            System.out.println(1);
            System.out.println(1);
        } else {
            System.out.println(1);
            System.out.println(1);
            int currentNo = 3;
            calFibRec(n, 1, 1, currentNo);
        }

    }

    public static void calFibRec(int n, int secondLast, int last,
            int currentNo) {
        if (currentNo <= n) {

            int sum = secondLast + last;
            System.out.println(sum);
            calFibRec(n, last, sum, ++currentNo);
        }
    }

}

1
public class febo 
{
 public static void main(String...a)
 {
  int x[]=new int[15];  
   x[0]=0;
   x[1]=1;
   for(int i=2;i<x.length;i++)
   {
      x[i]=x[i-1]+x[i-2];
   }
   for(int i=0;i<x.length;i++)
   {
      System.out.println(x[i]);
   }
 }
}

1

एक आंतरिक समवर्ती HashMap का उपयोग करके जो सैद्धांतिक रूप से इस पुनरावर्ती कार्यान्वयन को एक बहुपरत वातावरण में ठीक से संचालित करने की अनुमति दे सकता है, मैंने एक फ़ाइबर फ़ंक्शन लागू किया है जो BigInteger और Recursion दोनों का उपयोग करता है। पहले 100 फ़ाइब संख्या की गणना करने के लिए लगभग 53ms लेता है।

private final Map<BigInteger,BigInteger> cacheBig  
    = new ConcurrentHashMap<>();
public BigInteger fibRecursiveBigCache(BigInteger n) {
    BigInteger a = cacheBig.computeIfAbsent(n, this::fibBigCache);
    return a;
}
public BigInteger fibBigCache(BigInteger n) {
    if ( n.compareTo(BigInteger.ONE ) <= 0 ){
        return n;
    } else if (cacheBig.containsKey(n)){
        return cacheBig.get(n);
    } else {
        return      
            fibBigCache(n.subtract(BigInteger.ONE))
            .add(fibBigCache(n.subtract(TWO)));
    }
}

परीक्षण कोड है:

@Test
public void testFibRecursiveBigIntegerCache() {
    long start = System.currentTimeMillis();
    FibonacciSeries fib = new FibonacciSeries();
    IntStream.rangeClosed(0,100).forEach(p -&R {
        BigInteger n = BigInteger.valueOf(p);
        n = fib.fibRecursiveBigCache(n);
        System.out.println(String.format("fib of %d is %d", p,n));
    });
    long end = System.currentTimeMillis();
    System.out.println("elapsed:" + 
    (end - start) + "," + 
    ((end - start)/1000));
}
और परीक्षण से उत्पादन है:
    ।
    ।
    ।
    ।
    ।
    93 का फेन 12200160415121876738 है
    94 का फाइबर 19740274219868223167 है
    95 का फब 31940434634990099905 है
    96 का फेन 51680708854858323072 है
    97 का फब 83621143489848422977 है
    98 का ​​फब 135301852344706746049 है
    99 का फोब 218922995834555169026 है
    100 का फब 354224848179261915075 है
    गुजरे: 58,0

1

यहाँ एक पंक्ति फ़ेबोनैचि पुनरावर्ती है:

public long fib( long n ) {
        return n <= 0 ? 0 : n == 1 ? 1 : fib( n - 1 ) + fib( n - 2 );
}


0

बस पूरक करने के लिए, यदि आप बड़ी संख्या की गणना करने में सक्षम होना चाहते हैं, तो आपको बिगइंटर का उपयोग करना चाहिए।

एक पुनरावृत्त उदाहरण।

import java.math.BigInteger;
class Fibonacci{
    public static void main(String args[]){
        int n=10000;
        BigInteger[] vec = new BigInteger[n];
        vec[0]=BigInteger.ZERO;
        vec[1]=BigInteger.ONE;
        // calculating
        for(int i = 2 ; i<n ; i++){
            vec[i]=vec[i-1].add(vec[i-2]);
        }
        // printing
        for(int i = vec.length-1 ; i>=0 ; i--){
            System.out.println(vec[i]);
            System.out.println("");
        }
    }
}

0

अधिक विवरण में http://en.wikipedia.org/wiki/Fibnote_number

public class Fibonacci {

    public static long fib(int n) {
        if (n <= 1) return n;
        else return fib(n-1) + fib(n-2);
    }

    public static void main(String[] args) {
        int N = Integer.parseInt(args[0]);
        for (int i = 1; i <= N; i++)
            System.out.println(i + ": " + fib(i));
    }

}

इसे इतना सरल बनाएं कि लूप और अन्य लूप का उपयोग करने की आवश्यकता न हो


0
public class FibonacciSeries {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt();
        for (int i = 0; i <= N; i++) {
            int result = fibonacciSeries(i);
            System.out.println(result);
        }
        scanner.close();
    }

    private static int fibonacciSeries(int n) {
        if (n < 0) {
            return 1;
        } else if (n > 0) {
            return fibonacciSeries(n - 1) + fibonacciSeries(n - 2);
        }
        return 0;
    }
}

0

उपयोग करें while:

public int fib(int index) {
    int tmp = 0, step1 = 0, step2 = 1, fibNumber = 0;
    while (tmp < index - 1) {
        fibNumber = step1 + step2;
        step1 = step2;
        step2 = fibNumber;
        tmp += 1;
    };
    return fibNumber;
}

इस समाधान का लाभ यह है कि कोड को पढ़ना और समझना आसान है, उम्मीद है कि यह मदद करता है


0

एक Fibbonacci अनुक्रम वह है जो एक संख्या का परिणाम बताता है, फिर हमने पिछले परिणाम में जोड़ा है, हमें 1. से शुरू करना चाहिए। मैं एल्गोरिथ्म पर आधारित एक समाधान खोजने की कोशिश कर रहा था, इसलिए मैंने पुनरावर्ती कोड का निर्माण किया, ध्यान दिया कि मैं अलार्म रखता हूं पिछली संख्या और मैंने स्थिति बदल दी है। मैं 1 से 15 तक Fibbonacci अनुक्रम खोज रहा हूं।

public static void main(String args[]) {

    numbers(1,1,15);
}


public static int numbers(int a, int temp, int target)
{
    if(target <= a)
    {
        return a;
    }

    System.out.print(a + " ");

    a = temp + a;

    return numbers(temp,a,target);
}


-1

सिंपल फाइबोनैचि

public static void main(String[]args){

    int i = 0;
    int u = 1;

    while(i<100){
        System.out.println(i);
        i = u+i;
        System.out.println(u);
        u = u+i;
    }
  }
}

2
एसओ में आपका स्वागत है। जबकि आपका जवाब फाइबोनैचि अनुक्रम की गणना करता है। आपका जवाब ओपी का जवाब नहीं देता है, जिसने पुनरावर्ती कार्यों के बारे में पूछा है।
जेम्स के

-2

@chro पर हाजिर है, लेकिन वह इस पुनरावृत्ति को करने का सही तरीका नहीं दिखाता है। यहाँ समाधान है:

class Fib {
    static int count;

    public static void main(String[] args) {
        log(fibWrong(20));  // 6765
        log("Count: " + count); // 21891
        count = 0;
        log(fibRight(20)); // 6765
        log("Count: " + count); // 19
    }

    static long fibRight(long n) {
        return calcFib(n-2, 1, 1);
    }

    static long fibWrong(long n) {
        count++;
        if (n == 0 || n == 1) {
            return n;
        } else if (n < 0) {
            log("Overflow!");
            System.exit(1);
            return n;
        } else {
            return fibWrong(n-1) + fibWrong(n-2);
        }

    }

    static long calcFib(long nth, long prev, long next) {
        count++;
        if (nth-- == 0)
            return next;
        if (prev+next < 0) {
            log("Overflow with " + (nth+1) 
                + " combinations remaining");
            System.exit(1);
        }
        return calcFib(nth, next, prev+next);
    }

    static void log(Object o) {
        System.out.println(o);
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.