Fibonacci Dizisi nasıl yazılır?


140

Başlangıçta programı yanlış kodlamıştım. Fibonacci sayılarını bir aralık (örn. StartNumber 1, endNumber 20 = sadece 1 ve 20 arasındaki sayılar) arasında döndürmek yerine, programın bir aralık arasındaki tüm Fibonacci sayılarını görüntülemesi için yazdım (yani, startNumber 1, endNumber 20 görüntüler = İlk 20 Fibonacci numarası). Kesin bir yangın kodum olduğunu düşündüm. Bunun neden olduğunu da anlamıyorum.

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

Birisi Bölüm II'de (bu bir kopya olduğu için kapatıldı - /programming/504193/how-to-write-the-fibonacci-sequence-in-python-part-ii ) while döngüsü kullanarak startNumber ve endNumber öğelerini bir jeneratörden geçirmeniz gerekir. Birisi lütfen bunu nasıl yapacağım yönüne işaret edebilir mi? Herhangi bir yardım açığız.


Ben bir öğrenme programcısıyım ve biraz karmakarışık oldum. Bir kullanıcı tarafından girilen başlangıç ​​numarası ve bitiş numarası (yani, startNumber = 20 endNumber = 100) tarafından Fibonacci's Sequence hesaplamak ve görüntülemek için bir program yazmak istenir ve sadece bu aralık arasındaki sayıları gösterecektir). İşin püf noktası onu tamamen kullanmak (Python'da nasıl yapılacağını bilmiyorum? - Bunun kapsayıcı bir aralık kullanmak olduğunu varsayıyorum?).

Şimdiye kadar ne gerçek kodlama değil, daha ziyade:

  • Fib dizi formülünü sonsuza kadar yaz
  • Yalnızca Fib dizisinden startNumber ile endNumber arasındaki değerleri görüntüleyin.

Nereden başlayacağım konusunda hiçbir fikrim yok ve bunu nasıl yazacağım konusunda fikir veya fikir istiyorum. Ben de Fib dizisi forumla yazmaya çalıştım ama ben de kaybolmak.

Yanıtlar:


257

Wikipedia'da ve wolframda Fibonacci Dizisi hakkında birçok bilgi var . İhtiyacınız olandan çok daha fazlası. Her neyse, ihtiyacınız olanı (mümkünse hızlı bir şekilde) bulmak için bu kaynakları nasıl kullanacağınızı öğrenmek iyi bir şeydir.

Fib dizi formülünü sonsuza kadar yaz

Matematikte, özyinelemeli bir biçimde verilir:

wikipedia'dan fibonacci

Programlamada sonsuz yoktur. Matematik formunu doğrudan kendi dilinizde çeviren özyinelemeli bir form kullanabilirsiniz, örneğin Python'da:

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

En sevdiğiniz dilde deneyin ve n büyüdükçe bu formun çok zaman gerektirdiğini görün . Aslında, bu zaman içinde O (2 n ) 'dir.

Size bağlantı verdiğim sitelere devam edin ve bunu görün ( wolfram'da ):

Fibonacci Denklemi

Bu, Python'da uygulanması oldukça kolaydır ve hesaplaması çok çok hızlıdır:

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

Bunu yapmanın başka bir yolu da tanımı ( wikipedia'dan ) takip etmektir :

Dizinin ilk sayısı 0, ikinci sayı 1'dir ve sonraki her sayı dizinin kendisinin önceki iki sayısının toplamına eşittir ve diziyi 0, 1, 1, 2, 3, 5, 8 verir , vb.

Diliniz yineleyicileri destekliyorsa aşağıdakine benzer bir şey yapabilirsiniz:

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

Yalnızca Fib dizisinden startNumber ile endNumber arasındaki değerleri görüntüleyin.

Fibonacci Sayılarını nasıl üreteceğinizi öğrendikten sonra, sadece sayılar arasında geçiş yapmanız ve verilen koşulları doğrulayıp doğrulamadıklarını kontrol etmeniz yeterlidir.

Şimdi Fibonacci Sekansının n. Terimini döndüren af ​​(n) yazdığınızı varsayalım (sqrt (5) olana benzer)

Çoğu dilde aşağıdakileri yapabilirsiniz:

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

Python'da yineleyici formunu kullanır ve şuna giderim:

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

İpucu, ihtiyacınız olanı okumayı öğrenmek . Project Euler (bunun için google) bunu yapmanız için sizi eğitecek: P İyi şanslar ve iyi eğlenceler!


1
Harita yerine bir while döngüsü kullanmanız gerekir. Kendi başınıza anlamaya çalışın, sonra yapamazsanız kodla geri dönün. Tembel değilim (kod bu yorumdan daha kısa). Bunu senin için yapıyorum, "while" ipucu ile dene;) Eğer bununla ilgili bir sorun varsa tekrar gel;)
Andrea Ambu

Geri döndüm, lol. Harita (aralık) işlevinden kurtuldum ve sadece bir aralık (startNumber, endNumber) işlevi kullanıyorum. Şimdi sahip olduğum problem while ifadesini nerede kullanacağım. Ben fonksiyonun başında denemek ama tabii bir billin bitmiş bir hata satırları var. Nereye koymalıyım? Teşekkürler
SD.

Elle, programınızın giriş-çıkış örneğini (kısa bir aralık ile) yapmaya çalışın. Ardından programınızın nerede yanlış olduğunu anlamaya çalışın. Kodda "elle yöntem" dönüştürmeyi deneyin. Bu egzersiz, öğrenmek içindir. İki satır kod yazabilirim ama onlardan bir şey öğreneceğinizi sanmıyorum.
Andrea Ambu

1
int(((1+sqrt(5))**n-(1-sqrt(5))**n)/(2**n*sqrt(5)))Herhangi bir fikir kullanmalıyız ? @AndreaAmbu
lord63. j

3
@ lord63.j, bu formülü yalnızca n70'in üzerinde olduğunda gerçek değerden sapmaya başladığını ve 600'ün biraz üzerinde OverflowError olduğunda patladığını biliyorsanız, ndiğer yaklaşımlar nüfleme olmadan 1000 veya daha fazla işlem yapabilir hassasiyet veya kayıp.
cdlane

66

Fibonacci dizisinin verimli Pythonic jeneratörü

Bu dizinin en kısa Pythonic neslini elde etmeye çalışırken bu soruyu buldum (daha sonra bir Python Geliştirme Teklifinde benzer bir tane gördüğümü fark ettim) ve özel çözümümle başka kimsenin geldiğini fark etmedim (en iyi cevap yaklaşıyor, ancak yine de daha az zarif), işte burada, ilk yinelemeyi açıklayan yorumlar ile, çünkü okuyucuların anlamasına yardımcı olabilir:

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)

ve kullanım:

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

baskılar:

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

(Atıf amacıyla, Geçenlerde bir fark benzer uygulama bile değişkenleri kullanarak, modülleri Python belgelerinde ave bşimdi bu cevabı yazmadan önce gördükten hatırlamak. Ama bu yanıt dilin daha iyi kullanımını gösteren düşünüyorum.)

Yinelemeli olarak tanımlanmış uygulama

Tamsayı Dizilerin Çevrimiçi Ansiklopedisi olarak yinelemeli Fibonacci Dizisi tanımlar

F (n) = F (n-1) + F (n-2) ile F (0) = 0 ve F (1) = 1

Bunu Python'da özyineli olarak tanımlayan aşağıdaki gibi yapılabilir:

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

Ancak, matematiksel tanımın bu tam gösterimi 30'dan büyük sayılar için inanılmaz derecede verimsizdir, çünkü hesaplanan her sayı, altındaki her sayı için de hesaplanmalıdır. Aşağıdakileri kullanarak ne kadar yavaş olduğunu gösterebilirsiniz:

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

Verimlilik için not edilmiş özyineleme

Hızı artırmak için not edilebilir (bu örnek, işlev her çağrıldığında varsayılan bir anahtar kelime bağımsız değişkeninin aynı nesne olduğu gerçeğinden yararlanır, ancak normalde tam olarak bu nedenle değiştirilebilir bir varsayılan bağımsız değişken kullanmazsınız):

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

Memoized sürümünün çok daha hızlı olduğunu ve kahve almaya kalkmadan önce maksimum özyineleme derinliğinizi hızla aşacağını göreceksiniz. Bunu yaparak görsel olarak ne kadar hızlı olduğunu görebilirsiniz:

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

(Aşağıdakileri yapabileceğimiz gibi görünebilir, ancak aslında önbellekten faydalanmamıza izin vermez, çünkü setdefault çağrılmadan önce kendini çağırır.)

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

Özyinelemeli tanımlı jeneratör:

Haskell öğrenirken, Haskell'de bu uygulama ile karşılaştım:

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

Ben şu anda Python bu alabilirsiniz düşünüyorum en yakın:

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

Bu bunu gösterir:

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

Yine de, özyineleme sınırına kadar çıkabilir. Genellikle 1000, Haskell sürümü 100 milyona kadar çıkabiliyor, ancak bunu yapmak için dizüstü bilgisayarımın hafızasının tamamını kullanıyor olsa da:

> length $ take 100000000 fib 
100000000

Nci fibonacci numarasını almak için iteratörü kullanma

Bir yorumcu soruyor:

Yineleyiciye dayalı Fib () işlevi için soru: n., Örneğin 10. fib numarasını almak istiyorsanız ne olacak?

İtertools belgelerinin bunun için bir tarifi vardır:

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)

ve şimdi:

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

Son '' 'bunu yapma' '' seçeneği hakkında, varsayılan ayardan önce neden kendini çağıracağını anlamıyorum. N geçerli bir anahtarsa ​​setdefault öğesinin değeri döndürmesi gerekmez mi? Doc, "Anahtar sözlükte bulunuyorsa, değerini döndürün. Değilse, varsayılan değeri olan bir anahtar girin ve varsayılanı döndürün. Varsayılan varsayılanlar Hiçbiri'dir." Neyi kaçırıyorum ?
binithb

@binithb setdefaultçağrı içindeki ifade önce değerlendirilir setdefault.
Aaron Hall

23

Neden sadece aşağıdakileri yapmıyorsunuz?

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

21

Fibonacci dizisinin arkasındaki fikir aşağıdaki Python kodunda gösterilmiştir:

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

Bu, fib'in üç şeyden birini yapabilen bir işlev olduğu anlamına gelir. Fib (1) == 1, fib (0) == 0 ve fib (n) 'yi şu şekilde tanımlar:

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

Burada n, isteğe bağlı bir tamsayıdır. Bu, örneğin fib (2) 'nin aşağıdaki aritmetiğe genişlediği anlamına gelir:

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

Fib (3) 'ü aşağıda gösterilen aritmetik ile aynı şekilde hesaplayabiliriz:

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

Burada fark edilmesi gereken önemli olan, fib (3) ve fib (0) tanımları bilinerek hesaplanan fib (2) hesaplanmadan hesaplanamayacağıdır. Fibonacci işlevinin yaptığı gibi bir işleve sahip olmak özyineleme olarak adlandırılır ve programlamada önemli bir konudur.

Bu bir ev ödevi gibi geliyor, bu yüzden sizin için başlangıç ​​/ bitiş bölümünü yapmayacağım. Python bunun için harika bir ifade dilidir, bu yüzden matematiği anlarsanız bu mantıklı olmalıdır ve umarım size özyineleme hakkında bilgi verir. İyi şanslar!

Düzenleme: Kodumun potansiyel bir eleştiri, fib (n) işlevini çok daha kısa yapan süper kullanışlı Python işlev verimini kullanmamasıdır. Örneğim biraz daha genel, çünkü Python dışındaki pek çok dil aslında verime sahip değil.


Bu bir ev ödevi sorunu değil, vay canına cevap için teşekkür ederim! Ne yapmam gerektiğini anlıyorum ama başlamak ve uygulamak şimdi takıldığım şeydir (özellikle kullanıcı giriş değerlerini uygulamakla). Bununla ilgili fikir verebilir misiniz? 0x0141FAF0'da <function fib hatası alıyorum.
SD.

Mevcut yeteneğinizin ötesinde bir program uygulamak için çok uğraştığınızı anlıyorum. Daha fazla kod yazmam sana yardımcı olmaz. Çalışana kadar kodumla uğraşmaya çalışmalı ve daha fazla Python öğreticisi okumalısınız. Boşluk bir sorun olabilir, ancak bu hatayı bilmiyorum.
James Thompson

Anlıyorum. Kaybettiğimi düşündüğün başka bir fikir var mı? Ancak yardım edemiyorsanız anlıyorum. Zaman ayırdığınız için teşekkür ederim.
SD.

<Function fib at 0x0141FAF0> hatanız, işlevi çağıracak "fib ()" yerine "fib" (işlevin kendisine atıfta bulunur) demenin bir sonucu olabilir. İyi şanslar.
Kiv

8
Fibonacci sayılarını hesaplamak için bu saf özyinelemeli yöntemin yığın taşmasına (site değil) çok hızlı girebileceğini unutmayın. Pratik amaçlar için, yinelemeli olarak oluşturun veya bir tür not veya başka bir şey kullanın.
David Thornley

12

Zaman karmaşıklığı:

Önbellekleme özelliği , Fibonacci serisinin tekrarlayan ağacındaki tekrarları ortadan kaldırarak Fibonacci serisinin O (2 ^ n) ' den O (n)' ye hesaplanmasının normal yolunu azaltır :

resim açıklamasını buraya girin

Kod:

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

O (log n) temel aritmetik işlemler kullanılarak bu oldukça etkilidir.

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

Bu, O (1) temel aritmetik işlemleri kullanır, ancak ara sonuçların boyutu büyüktür ve bu nedenle hiç verimli değildir.

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

Bu, polinom halkası Z [X] / (X ^ 2 - X - 1) 'de X ^ n'yi kareleme yoluyla üs alma kullanarak hesaplar. Bu hesaplamanın sonucu, n. Fibonacci sayısının okunabildiği polinom Fib (n) X + Fib (n-1) 'dir.

Yine, bu O (log n) aritmetik işlemlerini kullanır ve çok etkilidir.

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
Birinci ve üçüncü teknikler iyidir. İkinci teknik 1 ile kapalıdır; etkin bir n -= 1şekilde düzgün çalışması gerekir ve aynı zamanda da çalışmaz n = 0. Her halükarda, bunların nasıl çalıştığını açıklamak için çok fazla bağlam eklenirse, özellikle de ilk teknik bana gerçekten yardımcı olacaktır. Paulhankin.github.io/Fibonacci
Acumenus'da

6

Fibonacci dizisini yazdırmak için kanonik Python kodu:

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

"1000 basamaktan daha uzun olan ilk Fibonacci numarasını yazdırın" sorunu için:

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

Biz biliyoruz ki

resim açıklamasını buraya girin

Ve bu matrisin n'inci gücü bize şunu verir:

resim açıklamasını buraya girin

Böylece, bu matrisin gücünü n-th -1 gücüne hesaplayan bir fonksiyon uygulayabiliriz.

bildiğimiz gibi a ^ n'nin gücü

resim açıklamasını buraya girin

Sonuçta fibonacci fonksiyonu O (n) olacaktır ... eğer biz de bunu bildiğimiz gerçeği olmasaydı x^n * x^n = x^2nve değerlendirilmesinin x^nO karmaşıklığıyla yapılabileceği gerçeği daha kolay bir uygulamadan farklı olmazdı (log n )

İşte hızlı programlama dili kullanarak benim fibonacci uygulaması:

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
}

Bunun karmaşıklığı O'dur (log n). Q'nun gücünü n-1 üsüyle hesaplıyoruz ve sonra n-1 güç üssünde tam olarak istediğimiz n-th Fibonacci sayısı olan F00 + 1 olan m00 elemanını alıyoruz.

Hızlı fibonacci fonksiyonuna sahip olduğunuzda, ilgilendiğiniz Fibonacci dizisinin bir kısmını elde etmek için başlangıç ​​ve bitiş numaralarından tekrarlayabilirsiniz.

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

Tabii ki, önce geçerli bir aralık oluşturabildiklerinden emin olmak için başlangıç ​​ve bitişte biraz kontrol yapın.

Sorunun 8 yaşında olduğunu biliyorum, ama yine de cevaplamakta çok eğlendim. :)


3

Fibonacci dizisidir: 1, 1, 2, 3, 5, 8, ....

Olduğunu f(1) = 1, f(2) = 1, f(3) = 2, ..., f(n) = f(n-1) + f(n-2).

En sevdiğim uygulama (diğer uygulamalara kıyasla en basit ve yine de hafif bir hız elde ediyor):

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

Ölçek

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

Zamanlama

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

Düzenle: bu uygulamalar için örnek bir görselleştirme .


3

özyineleme kullanın:

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

Bunu yapmanın başka bir yolu:

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

Listeyi 'a' olarak atamak, 'n' Haritasına ve azaltmak için tamsayı atamak python'daki en güçlü üç işlevden 2'sidir. Burada harita sadece 'n-2' kez tekrarlamak için kullanılır. a [-2:] bir dizinin son iki öğesini alır. a.append (x + y) son iki öğeyi ekler ve diziye ekler


1

Bunların hepsi olması gerekenden biraz daha karmaşık görünüyor. Kodum çok basit ve hızlı:

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
Dinamik programlama FTW! fibonacci (100000000000000000000000000000000000000000000000000000000000000000000000000000) neredeyse anında yanıt veriyor
Hans

6
Bir şekilde şüpheliyim.
Mart'ta Lanaru

Listeden sonra kaldırma komutundan kaçınmak için listeyi [0, 1] (yani List.append (0); List.append (1)) olarak başlatmaya ne dersiniz? ... ve fibonacci (10), 10'uncu olanı değil, 10'un altındaki fibonacci sayılarını döndürdüğü için fibonacci sayısı daha iyi endekslenmelidir.
SeF

1

Tamam .. tüm uzun cevaplardan bahsetmekten bıktıktan sonra, şimdi Fibonacci'yi python'da uygulamak için aşağıdaki sıralamayı ve tatlı, oldukça basit yolu bulun. Bir argüman alarak ya da kullanıcı girdisi alarak bunu istediğiniz gibi geliştirebilirsiniz… ya da limitleri 10000'den değiştirebilirsiniz.

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

Bu yaklaşım da iyi bir performans sergiliyor. Çalışma analizini aşağıda bulabilirsiniz

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

1

Bu, henry'nin cevabını mathew etmek için bir gelişme:

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

kod c yazdırmak yerine b yazdırmalıdır

çıktı: 1,1,2,3,5 ....


1

Döngü ve baskı için sadece sonucu kullanma

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

Sonuç

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

listTüm sayıları içeren yazdır

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

Sonuç

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

Sonuçlar

[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, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296, 433493, 433493, 433493, 433493, 433493, 433493 , 12586269025, 20365011074, 32951280099, 53316291173, 86267571272, 139583862445, 225851433717, 365435296162, 591286729879, 956722026041, 1548008755920, 2504730781961, 40527398808808808808808808808808808808808808808808808808198

çalışma süresi: 0.04298138618469238


1

bunu gerçekleştirmek için çok kolay bir yöntem var!

http://www.learnpython.org/ adresini kullanarak bu kodu çevrimiçi olarak özgürce çalıştırabilirsiniz.

# 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]

Karmaşık Özyineleme veri yapısı olmadan sadece yineleyici kullanarak Fibonacci serisini gerçekleştirmenin kolay bir yolu!
xgqfrms

1

Aşağıdaki yolla yapılabilir.

n = 0

sayılar = [0]

(0,11) aralığında i için:
    baskı n,
    numbers.append (n)
    prev = sayılar [-2]
    n == 0 ise:
        n = 1
    Başka:
        n = n + önceki

1

Sadece eğlence için, Python 3.8+ sürümünde bir liste ifadesinde bir atama ifadesi (mors operatörü olarak da bilinir) kullanabilirsiniz, örneğin:

>>> 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]

Atama ifadesi bir değişkene bir değer atamak için izin verir ve aynı ifadede iade. Bu nedenle, ifade

b := a + (a := b)

yürütmeye eşdeğerdir

a, b = b, a + b

değerini döndürme b.


0

Python öğrenirken kullandığım bir öğreticiden 15 dakika sonra, okuyucudan 3 giriş numarasından (ilk Fibonacci numarası, ikinci sayı ve diziyi durduracak sayı) bir Fibonacci dizisini hesaplayacak bir program yazmasını istedi. Eğitici yalnızca / thens ise değişkenleri kapsıyordu ve o noktaya kadar döngü yapıyor. Henüz işlev yok. Aşağıdaki kodu ile geldim:

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

Gördüğünüz gibi, gerçekten verimsiz, ama işe yarıyor.


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())burada gerekli değildir; Bence int(input())durum daha iyi.
GingerPlusPlus

0

Sadece http://projecteuler.net/problem=2 geçiyor bu benim almak oldu

# 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

Belki bu yardımcı olur

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

0

klasik fibonacci dizisine dayanır ve sadece tek gömlekler uğruna

sadece indeks sayısına ihtiyacınız varsa, azaltmayı kullanabilirsiniz ( azaltma bunun için en uygun olmasa bile , iyi bir egzersiz olabilir)

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]

ve dizinin tamamını almak için veya (r.pop (0) ve 0)

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

0

Buna ne dersin? Sanırım diğer öneriler kadar süslü değil, çünkü beklenen çıktıyı üretmek için önceki sonucun ilk spesifikasyonunu talep ediyor, ancak çok okunabilir bir seçenek olduğunu hissediyorum, yani tek yaptığı sonuç ve önceki sonucu sağlamak özyineleme.

#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)

İşte çıktı:

0
1
1
2
3
5
8
13
21
34
done

0

Temel olarak Ruby'den tercüme edilmiştir:

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

Memoization'ın Fibonacci dizisi için nasıl çalıştığına dair daha ayrıntılı bir açıklama.

# 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

Bu sorunu çözmek için özyinelemeli bir işlevden kaçınmaya çalışıyordum, bu yüzden yinelemeli bir yaklaşım izledim. Başlangıçta bir memoized özyinelemeli işlevi yapıyordum ama maksimum özyinelemeli derinliği vurmaya devam etti. Ben de sıkı bellek hedefleri vardı, bu yüzden bana dizi döngü sırasında herhangi bir zamanda dizide sadece 2-3 değer tutarak olabildiğince küçük tutmak göreceksiniz.

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

Makinemde 6 milyonuncu fibonacci sayısının elde edilmesi yaklaşık 282 saniye sürerken, 600k fibonacci sadece 2.8 saniye sürüyor. Yinelenen bir işleve, hatta hatırlatılmış bir işleve sahip bu kadar büyük fibonacci sayılarını elde edemedim.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.