web-dev-qa-db-ja.com

フィボナッチ数の反復アルゴリズム

私はフィボナッチ数の反復アルゴリズムに興味があるので、wikiで式を見つけました...それはまっすぐに見えるので、Pythonで試してみました...コンパイルに問題はなく、式は正しく見えます...なぜそれが間違った出力を与えるのか...私はそれを正しく実装しなかったのですか?

def fib (n): 
    if( n == 0):
        return 0
    else:
        x = 0
        y = 1
        for i in range(1,n):
            z = (x + y)
            x = y
            y = z
            return y

for i in range(10):
    print (fib(i))

出力


なし
1
1
1
1
1
1

15
Ris

問題は、_return y_が関数のループ内にあることです。したがって、最初の反復の後、すでに停止して最初の値を返します。1。nが0の場合を除き、その場合、関数は_0_自体を返し、nが1の場合ループは一度も繰り返されず、returnは実行されません(したがって、Noneの戻り値)。

これを修正するには、_return y_をループの外側に移動するだけです。

代替実装

KebertXの例に続いて、私が個人的にPythonで作成するソリューションを次に示します。もちろん、多くのフィボナッチ値を処理する場合、これらの2つのソリューションを組み合わせて、数値のキャッシュを作成することもできます。

_def f(n):
    a, b = 0, 1
    for i in range(0, n):
        a, b = b, a + b
    return a
_
52
poke

ループ内で値を返すため、yの値が1を超える前に関数が終了します。

私がもっと短く、もっと多くのpythonfulを提案するかもしれない場合:

def fibs(n):                                                                                                 
    fibs = [0, 1, 1]                                                                                           
    for f in range(2, n):                                                                                      
        fibs.append(fibs[-1] + fibs[-2])                                                                         
    return fibs[n]

これはアルゴリズムとまったく同じことを行いますが、3つの一時変数を作成する代わりに、それらをリストに追加し、インデックスごとにn番目のフィボナッチ数を返します。

4
KebertX

Pythonの非再帰的フィボナッチ数列

def fibs(n):
    f = []
    a = 0
    b = 1
    if n == 0 or n == 1:
        print n
    else:
        f.append(a)
        f.append(b)
        while len(f) != n:
            temp = a + b
            f.append(temp)
            a = b
            b = temp

    print f

fibs(10)

出力:[0、1、1、2、3、5、5、8、13、21、34]

1
karuna

Fib(0)では、次の理由で0を返します。

if (n == 0) {
    return 0;
}

Fib(1)では、次の理由で1を返します。

y = 1
return y

Fig(2)では、次の理由で1を返します。

y = 1
return y

...等々。限り return yはループ内にあり、関数は毎回forループの最初の反復で終了します。

他のユーザーが思いついた良い解決策は次のとおりです。 Pythonでフィボナッチ数列を書く方法

1
John Hornsby

別の可能なアプローチ:

a=0
b=1
d=[a,b]
n=int(input("Enter a number"))
i=2
while i<n:
    e=d[-1]+d[-2]
    d.append(e)
    i+=1
print("Fibonacci series of {} is {}".format(n,d))
0
Loki

この作品(直感的に

def fib(n):
    if n < 2:
        return n
    o,i = 0,1
    while n > 1:
        g = i
        i = o + i
        o = g
        n -= 1
    return i
0
MsO

このシンプルだが最速の方法はどうですか...(私はちょうど発見しました!)

def fib(n):
    x = [0,1]
    for i in range(n >> 1):
        x[0] += x[1]
        x[1] += x[0]
    return x[n % 2]

注意!結果として、この単純なアルゴリズムは、ループの長さが1/2に短縮され、各ループに2つの割り当てと2つの追加が含まれるため、1つの割り当てと1つの追加のみを使用します。

0
digitect38
fcount = 0 #a count recording the number of Fibonacci numbers generated
prev = 0
current = 0
next = 1
ll = 0 #lower limit
ul = 999 #upper limit

while ul < 100000:
    print("The following Fibonacci numbers make up the chunk between %d and %d." % (ll, ul))
    while next <= ul:
        print(next)
        prev = current
        current = next
        next = prev + current
        fcount += 1 #increments count

    print("Number of Fibonacci numbers between %d and %d is %d. \n" % (ll, ul, fcount))        
    ll = ul + 1 #current upper limit, plus 1, becomes new lower limit
    ul += 1000 #add 1000 for the new upper limit
    fcount = 0 #set count to zero for a new batch of 1000 numbers
0
Jedi_Jezzi
def fibiter(n):
    f1=1
    f2=1
    tmp=int()
    for i in range(1,int(n)-1):
        tmp = f1+f2
        f1=f2
        f2=tmp
    return f2

または並列割り当ての場合:

def fibiter(n):
    f1=1
    f2=1
    for i in range(1,int(n)-1):
        f1,f2=f2,f1+f2
    return f2

fibiter(4)を印刷します

0

別のスレッド でこれに遭遇しましたが、これは私が試した他の何よりもはるかに高速で、大量にタイムアウトすることはありません。数学への link です。

def fib(n):
    v1, v2, v3 = 1, 1, 0  
    for rec in bin(n)[3:]: 
        calc = v2*v2
        v1, v2, v3 = v1*v1+calc, (v1+v3)*v2, calc+v3*v3
        if rec=='1':    v1, v2, v3 = v1+v2, v1, v2
    return v2
0
user3464678