Come scrivere la sequenza di Fibonacci?


140

Inizialmente avevo programmato il programma in modo errato. Invece di restituire i numeri di Fibonacci tra un intervallo (es. StartNumber 1, endNumber 20 dovrebbe = solo quei numeri tra 1 e 20), ho scritto per il programma per visualizzare tutti i numeri di Fibonacci tra un intervallo (es. StartNumber 1, endNumber 20 visualizza = Primi 20 numeri di Fibonacci). Pensavo di avere un codice sicuro. Inoltre non vedo perché questo accada.

startNumber = int(raw_input("Enter the start number here "))
endNumber = int(raw_input("Enter the end number here "))

def fib(n):
    if n < 2:
        return n
    return fib(n-2) + fib(n-1)

print map(fib, range(startNumber, endNumber))

Qualcuno ha sottolineato nella mia Parte II (che è stata chiusa per essere un duplicato - /programming/504193/how-to-write-the-fibonacci-sequence-in-python-part-ii ) che I è necessario passare startNumber e endNumber attraverso un generatore usando un ciclo while. Qualcuno può indicarmi come fare? Qualsiasi aiuto è il benvenuto.


Sono un programmatore di apprendimento e ho incontrato un po 'di confusione. Mi viene chiesto di scrivere un programma che calcolerà e visualizzerà la sequenza di Fibonacci da parte di un numero di inizio e di un numero immessi dall'utente (es. StartNumber = 20 endNumber = 100 e visualizzerà solo i numeri tra quell'intervallo). Il trucco è usarlo inclusivamente (cosa che non so come fare in Python? - Suppongo che questo significhi usare un intervallo inclusivo?).

Quello che ho finora non è un vero codice ma piuttosto:

  • Scrivi la formula della sequenza Fib su infinito
  • Visualizza startNumber to endNumber solo dalla sequenza Fib.

Non ho idea di dove iniziare e sto chiedendo idee o approfondimenti su come scrivere questo. Ho anche provato a scrivere il forumla sequenza di Fib ma mi perdo anche su quello.

Risposte:


257

Ci sono molte informazioni sulla sequenza di Fibonacci su Wikipedia e su Wolfram . Molto più di quanto potresti aver bisogno. Comunque è una buona cosa imparare a usare queste risorse per trovare (se possibile rapidamente) ciò di cui hai bisogno.

Scrivi la formula della sequenza Fib su infinito

In matematica, è dato in una forma ricorsiva:

fibonacci da Wikipedia

Nella programmazione, non esiste infinito . Puoi usare un modulo ricorsivo traducendo il modulo matematico direttamente nella tua lingua, ad esempio in Python diventa:

def F(n):
    if n == 0: return 0
    elif n == 1: return 1
    else: return F(n-1)+F(n-2)

Provalo nella tua lingua preferita e vedi che questo modulo richiede molto tempo poiché n diventa più grande. In realtà, questo è O (2 n ) nel tempo.

Vai sui siti che ti ho collegato e vedrai questo (su wolfram ):

Equazione di Fibonacci

Questo è abbastanza facile da implementare e molto, molto veloce da calcolare, in Python:

from math import sqrt
def F(n):
    return ((1+sqrt(5))**n-(1-sqrt(5))**n)/(2**n*sqrt(5))

Un altro modo per farlo è seguire la definizione (da Wikipedia ):

Il primo numero della sequenza è 0, il secondo numero è 1 e ogni numero successivo è uguale alla somma dei due precedenti numeri della sequenza stessa, producendo la sequenza 0, 1, 1, 2, 3, 5, 8 , eccetera.

Se la tua lingua supporta gli iteratori, potresti fare qualcosa del tipo:

def F():
    a,b = 0,1
    while True:
        yield a
        a, b = b, a + b

Visualizza startNumber to endNumber solo dalla sequenza Fib.

Una volta che sai come generare i numeri di Fibonacci, devi solo scorrere i numeri e verificare se verificano le condizioni indicate.

Supponiamo che tu abbia scritto af (n) che restituisce l'ennesimo termine della sequenza di Fibonacci (come quello con sqrt (5))

Nella maggior parte delle lingue puoi fare qualcosa del tipo:

def SubFib(startNumber, endNumber):
    n = 0
    cur = f(n)
    while cur <= endNumber:
        if startNumber <= cur:
            print cur
        n += 1
        cur = f(n)

In Python userei il modulo iteratore e sceglierei:

def SubFib(startNumber, endNumber):
    for cur in F():
        if cur > endNumber: return
        if cur >= startNumber:
            yield cur

for i in SubFib(10, 200):
    print i

Il mio suggerimento è di imparare a leggere ciò di cui hai bisogno. Project Euler (google for it) ti insegnerà a farlo: P Buona fortuna e buon divertimento!


1
Devi usare un ciclo while, non una mappa. Prova a capirlo da solo, quindi torna con il codice se non riesci a farlo. Non sono pigro (il codice è più corto di questo commento). Lo sto facendo per te, provalo con il suggerimento "while";) Se hai problemi con quello ritorna di nuovo;)
Andrea Ambu

Sono tornato, lol. Mi sono sbarazzato della funzione map (range) e sto usando solo una funzione range (startNumber, endNumber). Ora il problema che ho è dove usare l'istruzione while. Provo all'inizio della funzione, ma ovviamente c'è un errore e una riga di errore. Dove dovrei metterlo? Thx
SD.

Prova a fare, a mano, un esempio di input-output del tuo programma (con un intervallo breve). Prova quindi a capire dove il tuo programma è sbagliato. Prova a convertire il "metodo manuale" nel codice. Questo è per l'esercizio, per imparare. Potrei mettere due righe di codice ma non credo che imparerai nulla da loro.
Andrea Ambu,

1
Dovremmo usare int(((1+sqrt(5))**n-(1-sqrt(5))**n)/(2**n*sqrt(5)))qualche idea? @AndreaAmbu
lord63. j

3
@ lord63.j, dovresti usare quella formula solo se sei consapevole che inizia a deviare dal valore reale quando nè superiore a 70 e esplode con un OverflowError quando nè leggermente superiore a 600. Altri approcci possono gestire un valore ndi 1000 o più senza soffiare o perdere precisione.
cdlane,

66

Efficiente generatore pitonico della sequenza di Fibonacci

Ho trovato questa domanda mentre cercavo di ottenere la generazione Pythonic più breve di questa sequenza (rendendomi conto in seguito di averne visto una simile in una proposta di potenziamento di Python ) e non ho notato nessun altro trovare la mia soluzione specifica (sebbene la risposta migliore si avvicina, ma è ancora meno elegante), quindi eccolo qui, con commenti che descrivono la prima iterazione, perché penso che possa aiutare i lettori a capire:

def fib():
    a, b = 0, 1
    while True:            # First iteration:
        yield a            # yield 0 to start with and then
        a, b = b, a + b    # a will now be 1, and b will also be 1, (0 + 1)

e utilizzo:

for index, fibonacci_number in zip(range(10), fib()):
     print('{i:3}: {f:3}'.format(i=index, f=fibonacci_number))

stampe:

  0:   0
  1:   1
  2:   1
  3:   2
  4:   3
  5:   5
  6:   8
  7:  13
  8:  21
  9:  34
 10:  55

(Ai fini dell'attribuzione, di recente ho notato un'implementazione simile nella documentazione di Python sui moduli, anche usando le variabili ae b, che ora ricordo di aver visto prima di scrivere questa risposta. Ma penso che questa risposta dimostri un uso migliore del linguaggio.)

Implementazione definita in modo ricorsivo

L' enciclopedia online delle sequenze di numeri interi definisce la sequenza di Fibonacci in modo ricorsivo

F (n) = F (n-1) + F (n-2) con F (0) = 0 e F (1) = 1

La definizione succinta in modo ricorsivo in Python può essere fatta come segue:

def rec_fib(n):
    '''inefficient recursive function as defined, returns Fibonacci number'''
    if n > 1:
        return rec_fib(n-1) + rec_fib(n-2)
    return n

Ma questa esatta rappresentazione della definizione matematica è incredibilmente inefficiente per numeri molto più grandi di 30, perché ogni numero da calcolare deve anche calcolare per ogni numero sottostante. Puoi dimostrare quanto è lento utilizzando quanto segue:

for i in range(40):
    print(i, rec_fib(i))

Ricorsione memorizzata per efficienza

Può essere memorizzato per migliorare la velocità (questo esempio sfrutta il fatto che un argomento di parola chiave predefinito è lo stesso oggetto ogni volta che viene chiamata la funzione, ma normalmente non useresti un argomento di default mutabile proprio per questo motivo):

def mem_fib(n, _cache={}):
    '''efficiently memoized recursive function, returns a Fibonacci number'''
    if n in _cache:
        return _cache[n]
    elif n > 1:
        return _cache.setdefault(n, mem_fib(n-1) + mem_fib(n-2))
    return n

Scoprirai che la versione memorizzata è molto più veloce e supererà rapidamente la massima profondità di ricorsione prima ancora che tu possa pensare di alzarti per un caffè. Puoi vedere quanto è più veloce visivamente facendo questo:

for i in range(40):
    print(i, mem_fib(i))

(Può sembrare che possiamo semplicemente fare quanto segue, ma in realtà non ci consente di sfruttare la cache, perché si chiama da solo prima di chiamare setdefault.)

def mem_fib(n, _cache={}):
    '''don't do this'''
    if n > 1:  
        return _cache.setdefault(n, mem_fib(n-1) + mem_fib(n-2))
    return n

Generatore definito ricorsivamente:

Mentre stavo imparando Haskell, mi sono imbattuto in questa implementazione in Haskell:

fib@(0:tfib) = 0:1: zipWith (+) fib tfib

Il più vicino che penso di poter ottenere in questo momento in Python è:

from itertools import tee

def fib():
    yield 0
    yield 1
    # tee required, else with two fib()'s algorithm becomes quadratic
    f, tf = tee(fib()) 
    next(tf)
    for a, b in zip(f, tf):
        yield a + b

Questo lo dimostra:

[f for _, f in zip(range(999), fib())]

Tuttavia, può arrivare solo al limite di ricorsione. Di solito, 1000, mentre la versione di Haskell può arrivare a centinaia di milioni, anche se usa tutti gli 8 GB di memoria del mio laptop per farlo:

> length $ take 100000000 fib 
100000000

Consumare l'iteratore per ottenere l'ennesimo numero di fibonacci

Un commentatore chiede:

Domanda per la funzione Fib () che si basa sull'iteratore: cosa succede se si desidera ottenere l'ennesimo, ad esempio il decimo numero di fib?

La documentazione di itertools ha una ricetta per questo:

from itertools import islice

def nth(iterable, n, default=None):
    "Returns the nth item or a default value"
    return next(islice(iterable, n, None), default)

e adesso:

>>> nth(fib(), 10)
55

Sull'ultima opzione '' 'non farlo' '', non capisco perché si chiamerebbe prima di setdefault. Setdefault non dovrebbe restituire il valore se n è una chiave valida? Doc dice "Se la chiave è nel dizionario, restituisce il suo valore. In caso contrario, inserisci la chiave con un valore predefinito e restituisci il valore predefinito. Il valore predefinito è Nessuno." Cosa mi sto perdendo?
binithb,

@binithb l'espressione all'interno della setdefaultchiamata viene valutata prima di setdefault .
Aaron Hall

23

Perché non semplicemente fare quanto segue?

x = [1,1]
for i in range(2, 10):  
    x.append(x[-1] + x[-2]) 
print(', '.join(str(y) for y in x))

21

L'idea alla base della sequenza di Fibonacci è mostrata nel seguente codice Python:

def fib(n):
   if n == 1:
      return 1
   elif n == 0:   
      return 0            
   else:                      
      return fib(n-1) + fib(n-2)         

Ciò significa che fib è una funzione che può fare una delle tre cose. Definisce fib (1) == 1, fib (0) == 0 e fib (n) essere:

fib (n-1) + fib (n-2)

Dove n è un numero intero arbitrario. Ciò significa che fib (2), ad esempio, si espande alla seguente aritmetica:

fib(2) = fib(1) + fib(0)
fib(1) = 1
fib(0) = 0
# Therefore by substitution:
fib(2) = 1 + 0
fib(2) = 1

Possiamo calcolare fib (3) allo stesso modo con l'aritmetica mostrata di seguito:

fib(3) = fib(2) + fib(1)
fib(2) = fib(1) + fib(0)
fib(2) = 1
fib(1) = 1
fib(0) = 0
# Therefore by substitution:
fib(3) = 1 + 1 + 0

La cosa importante da capire qui è che fib (3) non può essere calcolato senza calcolare fib (2), che viene calcolato conoscendo le definizioni di fib (1) e fib (0). Avere una funzione chiamata come la funzione fibonacci si chiama ricorsione, ed è un argomento importante nella programmazione.

Sembra un compito a casa, quindi non ho intenzione di fare la parte iniziale / finale per te. Python è un linguaggio meravigliosamente espressivo per questo, quindi dovrebbe avere senso se capisci la matematica e, spero, ti insegnerà la ricorsione. In bocca al lupo!

Modifica: una potenziale critica del mio codice è che non usa il super utile rendimento della funzione Python, il che rende la funzione fib (n) molto più breve. Il mio esempio è un po 'più generico, dal momento che non molte lingue al di fuori di Python hanno effettivamente un rendimento.


Questo non è un problema di compiti a casa ma wow grazie per la risposta! Capisco cosa devo fare ma avviarlo e implementarlo è ciò su cui sono bloccato ora (specialmente con l'implementazione dei valori di input dell'utente). Puoi fornirci alcune informazioni in merito? Continuo a ricevere un errore <funzione fib a 0x0141FAF0>.
SD.

Capisco che stai provando molto duramente per implementare un programma che potrebbe essere al di là delle tue attuali capacità. Fammi scrivere più codice non ti aiuterà. Dovresti provare a hackerare il mio codice fino a quando non funziona, e leggi altri tutorial su Python. Gli spazi bianchi possono essere un problema, ma non conosco quell'errore.
James Thompson,

Capisco. C'è qualche altra idea che pensi che potrei mancare? Capisco se non puoi aiutare comunque. Ti ringrazio per il tuo tempo
SD.

Il tuo errore <function fib at 0x0141FAF0> potrebbe essere il risultato della frase "fib" (che si riferisce alla funzione stessa) invece di "fib ()" che chiamerà la funzione. Buona fortuna.
Kiv,

8
Tieni presente che questo ingenuo metodo ricorsivo per calcolare i numeri di Fibonacci può entrare nello stack overflow (non nel sito) molto velocemente. Ai fini pratici, generare in modo iterativo o utilizzare una sorta di memoization o qualcosa del genere.
David Thornley,

12

Complessità temporale:

La funzione di memorizzazione nella cache riduce il modo normale di calcolare la serie di Fibonacci da O (2 ^ n) a O (n) eliminando le ripetizioni nell'albero ricorsivo della serie di Fibonacci:

inserisci qui la descrizione dell'immagine

Codice :

import sys

table = [0]*1000

def FastFib(n):
    if n<=1:
        return n
    else:
        if(table[n-1]==0):
            table[n-1] = FastFib(n-1)
        if(table[n-2]==0):
            table[n-2] = FastFib(n-2)
        table[n] = table[n-1] + table[n-2]
        return table[n]

def main():
    print('Enter a number : ')
    num = int(sys.stdin.readline())
    print(FastFib(num))

if __name__=='__main__':
    main()

9

Questo è abbastanza efficiente, usando O (log n) operazioni aritmetiche di base.

def fib(n):
    return pow(2 << n, n + 1, (4 << 2*n) - (2 << n) - 1) % (2 << n)

Questo utilizza O (1) operazioni aritmetiche di base, ma la dimensione dei risultati intermedi è grande e quindi non è affatto efficiente.

def fib(n):
    return (4 << n*(3+n)) // ((4 << 2*n) - (2 << n) - 1) & ((2 << n) - 1)

Questo calcola X ^ n nell'anello polinomiale Z [X] / (X ^ 2 - X - 1) usando esponenziazione mediante quadratura. Il risultato di quel calcolo è il polinomio Fib (n) X + Fib (n-1), da cui è possibile leggere l'ennesimo numero di Fibonacci.

Ancora una volta, questo utilizza operazioni aritmetiche O (log n) ed è molto efficiente.

def mul(a, b):
        return a[0]*b[1]+a[1]*b[0]+a[0]*b[0], a[0]*b[0]+a[1]*b[1]

def fib(n):
        x, r = (1, 0), (0, 1)
        while n:
                if n & 1: r = mul(r, x)
                x = mul(x, x)
                n >>= 1
        return r[0]

1
La prima e la terza tecnica sono buone. La seconda tecnica è disattivata di 1; deve effettivamente n -= 1funzionare correttamente e non funziona n = 0. In ogni caso, mi aiuterebbe molto se fosse stato aggiunto un sacco di contesto per spiegare come funzionano, specialmente la prima tecnica. Vedo che hai un post su paulhankin.github.io/Fibonacci
Acumenus

6

Codice Python canonico per stampare la sequenza di Fibonacci:

a,b=1,1
while True:
  print a,
  a,b=b,a+b       # Could also use b=a+b;a=b-a

Per il problema "Stampa il primo numero di Fibonacci più lungo di 1000 cifre":

a,b=1,1
i=1
while len(str(a))<=1000:
  i=i+1
  a,b=b,a+b

print i,len(str(a)),a

4

Lo sappiamo

inserisci qui la descrizione dell'immagine

E che l'ennesima potenza di quella matrice ci dà:

inserisci qui la descrizione dell'immagine

Quindi possiamo implementare una funzione che calcola semplicemente la potenza di quella matrice alla potenza n-esima -1.

come tutti sappiamo che il potere a ^ n è uguale

inserisci qui la descrizione dell'immagine

Quindi alla fine la funzione fibonacci sarebbe O (n) ... niente di veramente diverso da un'implementazione più semplice se non fosse per il fatto che sappiamo anche che x^n * x^n = x^2ne la valutazione di x^npuò quindi essere fatta con complessità O (log n )

Ecco la mia implementazione di fibonacci usando un linguaggio di programmazione rapido:

struct Mat {
    var m00: Int
    var m01: Int
    var m10: Int
    var m11: Int
}

func pow(m: Mat, n: Int) -> Mat {
    guard n > 1 else { return m }
    let temp = pow(m: m, n: n/2)

    var result = matMultiply(a: temp, b: temp)
    if n%2 != 0 {
        result = matMultiply(a: result, b: Mat(m00: 1, m01: 1, m10: 1, m11: 0))
    }
    return result
}

func matMultiply(a: Mat, b: Mat) -> Mat {
    let m00 = a.m00 * b.m00 + a.m01 * b.m10
    let m01 = a.m00 * b.m01 + a.m01 * b.m11
    let m10 = a.m10 * b.m00 + a.m11 * b.m10
    let m11 = a.m10 * b.m01 + a.m11 * b.m11

    return Mat(m00: m00, m01: m01, m10: m10, m11: m11)
}

func fibonacciFast(n: Int) -> Int {

    guard n > 0 else { return 0 }
    let m = Mat(m00: 1, m01: 1, m10: 1, m11: 0)

    return pow(m: m, n: n-1).m00
}

Questo ha complessità O (log n). Calcoliamo la potenza di Q con l'esponente n-1 e quindi prendiamo l'elemento m00 che è Fn + 1 che all'esponente di potenza n-1 è esattamente l'ennesimo numero di Fibonacci che volevamo.

Una volta che hai la funzione fibonacci veloce, puoi scorrere il numero iniziale e il numero finale per ottenere la parte della sequenza di Fibonacci che ti interessa.

let sequence = (start...end).map(fibonacciFast)

ovviamente prima esegui un controllo all'inizio e alla fine per assicurarti che possano formare un intervallo valido.

So che la domanda ha 8 anni, ma mi sono divertito a rispondere comunque. :)


3

Sequenza di Fibonacci è: 1, 1, 2, 3, 5, 8, ....

Cioè f(1) = 1, f(2) = 1, f(3) = 2, ..., f(n) = f(n-1) + f(n-2).

La mia implementazione preferita (più semplice e tuttavia raggiunge una velocità della luce rispetto ad altre implementazioni) è questa:

def fibonacci(n):
    a, b = 0, 1
    for _ in range(1, n):
        a, b = b, a + b
    return b

Test

>>> [fibonacci(i) for i in range(1, 10)]
[1, 1, 2, 3, 5, 8, 13, 21, 34]

sincronizzazione

>>> %%time
>>> fibonacci(100**3)
CPU times: user 9.65 s, sys: 9.44 ms, total: 9.66 s
Wall time: 9.66 s

Modifica: una visualizzazione di esempio per queste implementazioni.


3

usa la ricorsione:

def fib(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fib(n-1) + fib(n-2)
x=input('which fibonnaci do you want?')
print fib(x)

2

Un altro modo di farlo:

a,n=[0,1],10
map(lambda i: reduce(lambda x,y: a.append(x+y),a[-2:]),range(n-2))

Assegnare la lista a 'a', assegnare numeri interi a 'n' Map e ridurre sono 2 delle tre funzioni più potenti in Python. Qui la mappa viene utilizzata solo per iterare i tempi 'n-2'. a [-2:] otterrà gli ultimi due elementi di un array. a.append (x + y) aggiungerà gli ultimi due elementi e si aggiungerà alla matrice


1

Sembrano tutti un po 'più complicati di quanto debbano essere. Il mio codice è molto semplice e veloce:

def fibonacci(x):

    List = []
    f = 1
    List.append(f)
    List.append(f) #because the fibonacci sequence has two 1's at first
    while f<=x:
        f = List[-1] + List[-2]   #says that f = the sum of the last two f's in the series
        List.append(f)
    else:
        List.remove(List[-1])  #because the code lists the fibonacci number one past x. Not necessary, but defines the code better
        for i in range(0, len(List)):
        print List[i]  #prints it in series form instead of list form. Also not necessary

2
Programmazione dinamica FTW! fibonacci (1000000000000000000000000000000000000000000000000000000000000000000000000000000000) risponde quasi istantaneamente
Hans

6
In qualche modo ne dubito.
Lanaru,

Che ne dici di avviare la lista come [0, 1] (cioè List.append (0); List.append (1)) per evitare il comando remove dopo l'altro? ... e il numero di fibonacci dovrebbe essere meglio indicizzato in quanto fibonacci (10) restituisce i numeri di fibonacci al di sotto di 10, non il decimo.
SeF,

1

OK .. dopo essersi stancato di riferire tutte le risposte lunghe, ora trova il modo seguente e dolce, piuttosto semplice per implementare Fibonacci in Python. È possibile migliorarlo nel modo desiderato ottenendo un argomento o ottenendo l'input dell'utente ... o modificando i limiti da 10000. Se necessario ...

def fibonacci():
    start = 0 
    i = 1 
    lt = []
    lt.append(start)
    while start < 10000:
        start += i
        lt.append(start)
        i = sum(lt[-2:])
        lt.append(i)
    print "The Fibonaccii series: ", lt

Anche questo approccio funziona bene. Trova le analisi della corsa di seguito

In [10]: %timeit fibonacci
10000000 loops, best of 3: 26.3 ns per loop

1

questo è un miglioramento alla risposta di Matthew Henry:

def fib(n):
    a = 0
    b = 1
    for i in range(1,n+1):
            c = a + b
            print b
            a = b
            b = c

il codice dovrebbe stampare b invece di stampare c

uscita: 1,1,2,3,5 ....


1

Usando per loop e stampa solo il risultato

def fib(n:'upto n number')->int:
    if n==0:
        return 0
    elif n==1:
        return 1
    a=0
    b=1
    for i in range(0,n-1):
        b=a+b
        a=b-a
    return b

Risultato

>>>fib(50)
12586269025
>>>>
>>> fib(100)
354224848179261915075
>>> 

Stampa il listcontenente tutti i numeri

def fib(n:'upto n number')->int:
    l=[0,1]
    if n==0:
        return l[0]
    elif n==1:
        return l
    a=0
    b=1
    for i in range(0,n-1):
        b=a+b
        a=b-a
        l.append(b)
    return l

Risultato

>>> fib(10)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

1
import time
start_time = time.time()



#recursive solution
def fib(x, y, upperLimit):
    return [x] + fib(y, (x+y), upperLimit) if x < upperLimit else [x]

#To test :

print(fib(0,1,40000000000000))
print("run time: " + str(time.time() - start_time))

risultati

[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368 , 75025, 121393, 196.418, 317.811, 514.229, 832.040, 1.346.269, 2.178.309, 3.524.578, 5.702.887, 9.227.465, 14.930.352, 24.157.817, 39.088.169, 63.245.986, 102.334.155, 165.580.141, 267.914.296, 433.494.437, 701.408.733, 1.134.903,17 mille, 1.836.311,903 mila, 2.971.215,073 mila, 4.807.526,976 mila, 7.778.742,049 mila , 12586269025, 20365011074, 32951280099, 53316291173, 86267571272, 139583862445, 225851433717, 365435296162, 591286729879, 956722026041, 1548008755920757 5775 4585 475

tempo di esecuzione: 0,04298138618469238


1

c'è un metodo molto semplice per rendersene conto!

puoi eseguire questo codice online liberamente usando http://www.learnpython.org/

# Set the variable brian on line 3!

def fib(n):
"""This is documentation string for function. It'll be available by fib.__doc__()
Return a list containing the Fibonacci series up to n."""
result = []
a = 0
b = 1
while a < n:
    result.append(a)  # 0 1 1 2 3 5  8  (13) break
    tmp_var = b       # 1 1 2 3 5 8  13
    b = a + b         # 1 2 3 5 8 13 21
    a = tmp_var       # 1 1 2 3 5 8  13
    # print(a)
return result

print(fib(10))
# result should be this: [0, 1, 1, 2, 3, 5, 8]

un modo semplice per realizzare la serie Fibonacci semplicemente usando iteratore, senza alcuna complessa struttura di dati di ricorsione!
xgqfrms,

1

Può essere fatto nel modo seguente.

n = 0

numeri = [0]

per i nell'intervallo (0,11):
    stampa n,
    numbers.append (n)
    prev = numeri [-2]
    se n == 0:
        n = 1
    altro:
        n = n + prev

1

Solo per divertimento, in Python 3.8+ è possibile utilizzare un'espressione di assegnazione ( nota anche come operatore tricheco) per la comprensione di un elenco, ad esempio:

>>> a, b = 0, 1
>>> [a, b] + [b := a + (a := b) for _ in range(8)]  # first 10 Fibonacci numbers
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

Un'espressione di assegnazione consente di assegnare un valore a una variabile e restituirlo nella stessa espressione. Pertanto, l'espressione

b := a + (a := b)

è equivalente all'esecuzione

a, b = b, a + b

e restituendo il valore di b.


0

15 minuti in un tutorial che ho usato durante l'apprendimento di Python, ha chiesto al lettore di scrivere un programma che calcolasse una sequenza di Fibonacci da 3 numeri di input (primo numero di Fibonacci, secondo numero e numero a cui fermare la sequenza). Il tutorial ha riguardato solo le variabili, se / thens, e esegue il loop fino a quel punto. Nessuna funzione ancora. Mi è venuto in mente il seguente codice:

sum = 0
endingnumber = 1                

print "\n.:Fibonacci sequence:.\n"

firstnumber = input("Enter the first number: ")
secondnumber = input("Enter the second number: ")
endingnumber = input("Enter the number to stop at: ")

if secondnumber < firstnumber:

    print "\nSecond number must be bigger than the first number!!!\n"

else:

while sum <= endingnumber:

    print firstnumber

    if secondnumber > endingnumber:

        break

    else:

        print secondnumber
        sum = firstnumber + secondnumber
        firstnumber = sum
        secondnumber = secondnumber + sum

Come puoi vedere, è davvero inefficiente, ma funziona.


0
def fib():
    a,b = 1,1
    num=eval(input("Please input what Fib number you want to be calculated: "))
    num_int=int(num-2)
    for i in range (num_int):
        a,b=b,a+b
    print(b)

3
eval(input())non è necessario qui; Penso che int(input())nel caso sia meglio.
GingerPlusPlus,

0

Basta andare su http://projecteuler.net/problem=2 questa è stata la mia opinione

# Even Fibonacci numbers
# Problem 2

def get_fibonacci(size):
    numbers = [1,2]
    while size > len(numbers):
        next_fibonacci = numbers[-1]+numbers[-2]
        numbers.append(next_fibonacci)

    print numbers

get_fibonacci(20)

0
def fib(x, y, n):
    if n < 1: 
        return x, y, n
    else: 
        return fib(y, x + y, n - 1)

print fib(0, 1, 4)
(3, 5, 0)

#
def fib(x, y, n):
    if n > 1:
        for item in fib(y, x + y, n - 1):
            yield item
    yield x, y, n

f = fib(0, 1, 12)
f.next()
(89, 144, 1)
f.next()[0]
55

0

Forse questo aiuterà

def fibo(n):
    result = []
    a, b = 0, 1
    while b < n:
            result.append(b)
            a, b = b, b + a
    return result

0

basato sulla classica sequenza di fibonacci e solo per il gusto di una linea

se hai solo bisogno del numero dell'indice, puoi usare la riduzione (anche se riduzione non è più adatto a questo, può essere un buon esercizio)

def fibonacci(index):
    return reduce(lambda r,v: r.append(r[-1]+r[-2]) or (r.pop(0) and 0) or r , xrange(index), [0, 1])[1]

e per ottenere l'array completo è sufficiente rimuovere o (r.pop (0) e 0)

reduce(lambda r,v: r.append(r[-1]+r[-2]) or r , xrange(last_index), [0, 1])

0

Che ne dici di questo? Immagino che non sia sofisticato come gli altri suggerimenti perché richiede la specifica iniziale del risultato precedente per produrre l'output previsto, ma ritengo sia un'opzione molto leggibile, cioè tutto ciò che fa è fornire il risultato e il risultato precedente a la ricorsione.

#count the number of recursions
num_rec = 0

def fibonacci(num, prev, num_rec, cycles):

    num_rec = num_rec + 1

    if num == 0 and prev == 0:
        result  = 0;
        num = 1;
    else:
        result = num + prev

    print(result)

    if num_rec == cycles:
        print("done")
    else:
        fibonacci(result, num, num_rec, cycles)

#Run the fibonacci function 10 times
fibonacci(0, 0, num_rec, 10)

Ecco l'output:

0
1
1
2
3
5
8
13
21
34
done

0

Fondamentalmente tradotto da Ruby:

def fib(n):
    a = 0
    b = 1
    for i in range(1,n+1):
            c = a + b
            print c
            a = b
            b = c

...


0
def fib(lowerbound, upperbound):
    x = 0
    y = 1
    while x <= upperbound:
        if (x >= lowerbound):
            yield x
        x, y = y, x + y

startNumber = 10
endNumber = 100
for fib_sequence in fib(startNumber, endNumber):
    print "And the next number is... %d!" % fib_sequence

0

Una spiegazione più dettagliata di come funziona la Memoization per la sequenza di Fibonacci.

# Fibonacci sequence Memoization

fib_cache = {0:0, 1:1}

def fibonacci(n):
    if n < 0:
        return -1
    if fib_cache.has_key(n):
        print "Fibonacci sequence for %d = %d cached" % (n, fib_cache[n])
        return fib_cache[n]
    else:
        fib_cache[n] = fibonacci(n - 1) + fibonacci(n - 2)
    return fib_cache[n]

if __name__ == "__main__":
    print fibonacci(6)
    print fib_cache
    # fibonacci(7) reuses fibonacci(6) and fibonacci(5)
    print fibonacci(7)
    print fib_cache

0

Stavo cercando di evitare una funzione ricorsiva per risolvere questo problema, quindi ho adottato un approccio iterativo. Inizialmente stavo facendo una funzione ricorsiva memorizzata ma continuavo a colpire la massima profondità ricorsiva. Avevo anche obiettivi di memoria rigidi, quindi mi vedrai mantenere l'array il più piccolo possibile durante il processo di loop mantenendo solo 2-3 valori nell'array in qualsiasi momento.

def fib(n):
    fibs = [1, 1] # my starting array
    for f in range(2, n):
        fibs.append(fibs[-1] + fibs[-2]) # appending the new fib number
        del fibs[0] # removing the oldest number
    return fibs[-1] # returning the newest fib

print(fib(6000000))

Ottenere il 6 milionesimo numero di fibonacci richiede circa 282 secondi sulla mia macchina, mentre il fibonacci da 600k richiede solo 2,8 secondi. Non sono stato in grado di ottenere numeri così grandi di fibonacci con una funzione ricorsiva, anche se memorizzata.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.