フィボナッチ数列の書き方は?


140

私はもともとプログラムを間違ってコーディングしていました。範囲内のフィボナッチ数を返すのではなく(つまり、startNumber 1、endNumber 20 = 1から20までの数値のみ)、範囲内のすべてのフィボナッチ数(つまり、startNumber 1、endNumber 20)を表示するようにプログラムを記述しました。表示=最初の20フィボナッチ数)。確実なコードがあると思った。なぜこれが起こっているのかもわかりません。

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

誰かが私のパートIIで指摘した(これは重複しているため閉鎖された-https ://stackoverflow.com/questions/504193/how-to-write-the-fibonacci-sequence-in-python-part-ii) whileNumberループを使用して、ジェネレータを介してstartNumberおよびendNumberを渡す必要があります。誰かが私にこれを行う方法の方向を教えてもらえますか?どんな助けでも大歓迎です。


私は学習プログラマーであり、少しごちゃごちゃしています。ユーザーが入力した開始番号と終了番号によってフィボナッチ数列を計算して表示するプログラムを作成するように求められます(つまり、startNumber = 20 endNumber = 100で、その範囲内の数値のみを表示します)。秘訣は、それを包括的に使用することです(これはPythonでの方法がわかりません?-これは包括的範囲を使用することを意味すると思いますか?)。

これまでのところ、実際のコーディングではなく、次のようになっています。

  • Fibシーケンス式を無限に書き込む
  • Fibシーケンスからのみ、startNumberからendNumberまでを表示します。

どこから始めればよいかわからないので、これを書く方法についてのアイデアや洞察を求めています。また、Fibシーケンスforumlaを作成しようとしましたが、それについても迷っています。

回答:


257

WikipediaWolframには、フィボナッチ数列に関する多くの情報があります。あなたが必要とするよりもはるかに多くの。とにかく、これらのリソースを使用して必要なものを(可能な場合は迅速に)見つける方法を学ぶことは良いことです。

Fibシーケンス式を無限に書き込む

数学では、それは再帰的な形で与えられます:

ウィキペディアのフィボナッチ

プログラミングでは、無限は存在しません。あなたはあなたの言語で直接数学のフォームを翻訳する再帰的なフォームを使うことができます、例えばPythonではそれは次のようになります:

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

お好みの言語で試してみてください。nが大きくなるとこのフォームには多くの時間がかかることがわかります。実際、これは時間のO(2 n)です。

私があなたにリンクしたサイトに行くと、これが表示されます(wolfram上):

フィボナッチ方程式

これは、Pythonでの実装が非常に簡単で、計算が非常に高速です。

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

それを行う別の方法は、(ウィキペディアからの)定義に従うことです:

シーケンスの最初の数は0、2番目の数は1、そして後続の各数はシーケンス自体の前の2つの数の合計に等しく、シーケンス0、1、1、2、3、5、8になります。 、など

あなたの言語がイテレータをサポートしているなら、あなたは次のようなことをするかもしれません:

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

Fibシーケンスからのみ、startNumberからendNumberまでを表示します。

フィボナッチ数列を生成する方法がわかったら、数値を循環させて、指定された条件を検証するかどうかを確認する必要があります。

ここで、フィボナッチ数列のn番目の項を返すaf(n)を記述したとします(sqrt(5)の場合と同様)。

ほとんどの言語では、次のようなことができます。

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

Pythonでは、イテレータフォームを使用して次のようにします。

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

私のヒントは、必要なものを読むことを学ぶことです。プロジェクトオイラー(Google for it)は、そうするように訓練します:P頑張って楽しんでください!


1
マップではなく、whileループを使用する必要があります。自分でそれを理解してみて、それができない場合はコードに戻ってください。私は怠惰ではありません(コードはこのコメントより短いです)。私はあなたのためにそれをやっています、 "while"ヒントで試してください;)再び問題が発生する場合は;)
Andrea Ambu

私は戻ってきました、笑。map(range)関数を削除し、range(startNumber、endNumber)関数のみを使用しています。今私が持っている問題は、whileステートメントをどこで使用するかです。関数の最初に試してみましたが、もちろんエラーの完了行があります。どこに置けばいいですか?Thx
SD。

プログラムの入出力の例を(手短に)手動で実行してみてください。次に、プログラムのどこが間違っているかを調べてください。コードで「手動メソッド」を変換してみてください。これは運動のために、学ぶためです。私は2行のコードを書き留めることができましたが、それらから何も学ぶことはないと思います。
アンドレア・アンブ

1
私たちはint(((1+sqrt(5))**n-(1-sqrt(5))**n)/(2**n*sqrt(5)))、何かアイデアを使うべきですか?@AndreaAmbu
lord63。j

3
@ lord63.j、n70を超えると実際の値から逸脱し始め、OverflowError when nが600をわずかに超えると爆発することを知っている場合にのみ、この式を使用する必要があります。他のアプローチでは、nブローせずに1000以上を処理できます精度が上がったり失われたりします。
cdlane 2017

66

フィボナッチ数列の効率的なPythonicジェネレーター

私はこのシーケンスの最短のPythonic生成を取得しようとしたときにこの質問を見つけました(後で、Python拡張提案で同様のものが見られたことに気付きました)、私の特定の解決策を考えている人が他にいることに気づいていません(トップの答えは近づきますが、それでもエレガントではありません)。それで、読者が理解するのに役立つかもしれないと思うので、ここに、最初の反復を説明するコメントを付けます:

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)

および使用法:

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

プリント:

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

(属性の目的で、最近、変数とを使用していても、モジュールのPythonドキュメントに同様の実装があることに気付きました。これは、この回答を書く前に見たことがあることを思い出します。しかし、この回答は言語のより良い使用法を示していると思います。)ab

再帰的に定義された実装

整数シーケンスオンライン百科事典では、フィボナッチ数列を次のように再帰的に定義しています。

F(n)= F(n-1)+ F(n-2)、F(0)= 0およびF(1)= 1

Pythonでこれを再帰的に簡潔に定義するには、次のようにします。

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

ただし、この正確な数学的定義の表現は、30を超える数値に対しては非常に非効率です。これは、計算される各数値が、それよりも小さいすべての数値に対しても計算する必要があるためです。次のようにして、速度がどれほど遅いかを示すことができます。

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

効率化のためのメモ化された再帰

速度を改善するためにメモすることができます(この例では、関数が呼び出されるたびにデフォルトのキーワード引数が同じオブジェクトであるという事実を利用していますが、通常、この理由から変更可能なデフォルト引数を使用しません)。

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

メモ化されたバージョンの方がはるかに高速であり、コーヒーに乗り出すと考える前に、最大の再帰の深さをすぐに超えてしまいます。これを実行すると、視覚的にどれほど高速かを確認できます。

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

(以下のようにできるだけのように見えるかもしれませんが、実際には、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

再帰的に定義されたジェネレータ:

私はHaskellを学んでいるので、Haskellでこの実装に出会いました。

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

私が現時点で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

これはそれを示しています:

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

ただし、再帰の限界までしか上がらない。通常は1000ですが、Haskellのバージョンは1億に達する可能性がありますが、私のラップトップのメモリの8 GBをすべて使用します。

> length $ take 100000000 fib 
100000000

イテレータを使用してn番目のフィボナッチ数を取得する

コメンターは尋ねます:

イテレータに基づくFib()関数の質問:n番目、たとえば10番目のfib番号を取得したい場合はどうなりますか?

itertoolsのドキュメントには、このためのレシピがあります。

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)

そして今:

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

最後の「 ''これを行わない」 ''オプションについて、setdefaultの前にそれ自体を呼び出す理由がわかりません。nが有効なキーである場合、setdefaultは値を返すことになっていますか?Docは、「キーがディクショナリにある場合は、その値を返します。そうでない場合は、デフォルトの値でキーを挿入してデフォルトを返します。デフォルトのデフォルトはなしです。」何が欠けていますか?
binithb 2017年

@binithb setdefault呼び出し内の式は前に 評価されsetdefaultます。
アーロンホール


21

フィボナッチ数列の背後にある考え方は、次のPythonコードに示されています。

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

これは、fibが3つのことの1つを実行できる関数であることを意味します。これは、fib(1)== 1、fib(0)== 0、およびfib(n)を次のように定義します。

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

ここで、nは任意の整数です。これは、たとえば、fib(2)が次の演算に展開されることを意味します。

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

以下に示す算術を使用して、同じ方法でfib(3)を計算できます。

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

ここで重要なのは、fib(1)とfib(0)の定義を知って計算されるfib(2)を計算しないと、fib(3)を計算できないことです。fibonacci関数のように関数を呼び出すことは再帰と呼ばれ、プログラミングでは重要なトピックです。

これは宿題のように聞こえるので、私はあなたのために開始/終了部分を行うつもりはありません。Pythonはこのための素晴らしく表現力のある言語なので、数学を理解していればこれは理にかなっているはずです。幸運を!

編集:私のコードに対する1つの潜在的な批判は、非常に便利なPython関数yieldを使用しないため、fib(n)関数が大幅に短くなることです。私の例は少し一般的ですが、Python以外の多くの言語では実際に歩留まりがありません。


これは宿題ではありませんが、お返事ありがとうございます!私は何をする必要があるかは理解していますが、それを開始して実装することは、(特にユーザー入力値の実装で)行き詰まっていることです。これについて洞察を提供できますか?<function fib at 0x0141FAF0>エラーが発生し続けます。
SD。

現在の能力を超える可能性のあるプログラムを実装するために懸命に努力しているとのことですが、もっとコードを書いても役に立たない。コードが機能するまでハックして、Pythonチュートリアルを読んでください。空白が問題になる可能性がありますが、そのエラーはわかりません。
James Thompson、

わかります。私が見逃していると思う他のアイデアはありますか?しかし、あなたが助けられないなら、私は理解します。お時間をいただきありがとうございます。
SD。

<function fib at 0x0141FAF0>エラーは、関数を呼び出す "fib()"ではなく、 "fib"(関数自体を参照)と言った結果である可能性があります。幸運を祈ります。
Kiv

8
フィボナッチ数を計算するこの素朴な再帰的な方法は、スタックオーバーフロー(サイトではない)に非常に速く入る可能性があることに注意してください。実用的な目的のために、繰り返し生成するか、何らかのメモや何かを使用します。
David Thornley、

12

時間の複雑さ:

キャッシング機能は、フィボナッチシリーズの再帰ツリーの繰り返しを排除することで、フィボナッチシリーズをO(2 ^ n)からO(n)に計算する通常の方法を削減します。

ここに画像の説明を入力してください

コード:

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)の基本的な算術演算を使用して非常に効率的です。

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

これはO(1)の基本的な算術演算を使用しますが、中間結果のサイズは大きく、そのためまったく効率的ではありません。

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

これは、二乗による指数を使用して、多項式リングZ [X] /(X ^ 2-X-1)のX ^ nを計算します。その計算の結果は、多項式Fib(n)X + Fib(n-1)で、そこからn番目のフィボナッチ数を読み取ることができます。

繰り返しになりますが、これはO(log n)算術演算を使用しており、非常に効率的です。

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
1番目と3番目の手法は優れています。2番目の手法は1オフです。効果的にn -= 1正しく動作する必要があり、でも動作しませんn = 0。いずれにせよ、これらがどのように機能するかを説明するために、特に最初の手法を説明するために多くのコンテキストが追加されていれば、本当に助かります。paulhankin.github.io/Fibonacciに
Acumenus

6

フィボナッチ数列を出力する正規Pythonコード:

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

「1000桁を超える最初のフィボナッチ数を印刷する」という問題の場合:

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

私達はことを知っています

ここに画像の説明を入力してください

そして、その行列のn乗により、次のようになります。

ここに画像の説明を入力してください

したがって、その行列の累乗をn -1の累乗で単純に計算する関数を実装できます。

パワーa ^ nは

ここに画像の説明を入力してください

したがって、最後にフィボナッチ関数はO(n)になります...それもわかっているという事実がなければ、簡単な実装と何も変わりません。したがってx^n * x^n = x^2n、評価はx^n複雑さO(log n )

ここに迅速なプログラミング言語を使用した私のフィボナッチ実装があります:

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
}

これにはO(log n)の複雑さがあります。指数n-1でQのo乗を計算し、次に指数n-1で必要なn番目のフィボナッチ数であるFn + 1である要素m00を取得します。

高速フィボナッチ関数を取得したら、開始番号と終了番号から反復して、興味のあるフィボナッチシーケンスの一部を取得できます。

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

もちろん、最初に開始と終了をチェックして、有効な範囲を形成できることを確認します。

質問は8歳ですが、とにかく楽しく答えました。:)


3

フィボナッチ数列は次のとおり1, 1, 2, 3, 5, 8, ...です。

つまりf(1) = 1f(2) = 1f(3) = 2...f(n) = f(n-1) + f(n-2)

私のお気に入りの実装(最も単純でありながら、他の実装と比較して軽い速度を実現)は次のとおりです。

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

テスト

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

タイミング

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

編集:この実装の視覚化の例


3

再帰を使用する:

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

それを行う別の方法:

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

リストを 'a'に割り当てる、整数を 'n'に割り当てるMapおよびreduceは、Pythonで最も強力な3つの関数のうちの2つです。ここでは、マップは単に「n-2」回繰り返すために使用されます。a [-2:]は、配列の最後の2つの要素を取得します。a.append(x + y)は最後の2つの要素を追加し、配列に追加します


1

これらはすべて必要以上に複雑に見えます。私のコードは非常にシンプルで高速です:

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
動的プログラミングFTW!fibonacci(100000000000000000000000000000000000000000000000000000000000000000000000000000)はほぼ瞬時に応答します
Hans

6
どういうわけか私はそれを疑います。
ラナル

リストを[0、1](つまり、List.append(0); List.append(1))として開始して、elseの後の削除コマンドを回避しますか?...そして、フィボナッチ数は10のフィボナッチ数ではなく10未満のフィボナッチ数を返すため、フィボナッチ数はより適切にインデックス化されるべきです。
SeF

1

OK ..長い答えをすべて参照するのに疲れた後、Pythonでフィボナッチを実装するための次の並べ替えと甘い、かなり簡単な方法を見つけてください。引数を取得したり、ユーザー入力を取得したり、制限を10000から変更したりして、必要に応じて拡張できます。必要に応じて……

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

このアプローチも効果的です。以下の実行分析を見つけます

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

1

これはマシュー・ヘンリーの答えの改善です:

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

コードはcを印刷する代わりにbを印刷する必要があります

出力:1,1,2,3,5 ....


1

forループを使用して結果のみを出力する

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

結果

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

listすべての数字を含むを印刷します

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

結果

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

結果

[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、433494437、701408733、1134903170、18150731137905261236373790 、12586269025、20365011074、32951280099、53316291173、86267571272、139583862445、225851433717、365435296162、591286729879、956722026041、1548008755920、2504730781961、4052739537881、6557470319842、10610209857723、17167680177565、9457512777853、29457890035565

実行時間:0.04298138618469238


1

それを実現する非常に簡単な方法があります!

このコードは、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]

複雑な再帰データ構造なしで、イテレータを使用するだけでフィボナッチシリーズを実現する簡単な方法!
xgqfrms 2016

1

以下の方法で行うことができます。

n = 0

数値= [0]

for i(0,11)の場合:
    プリントn、
    numbers.append(n)
    前=数値[-2]
    n == 0の場合:
        n = 1
    そうしないと:
        n = n +前へ

1

面白くするために、Python 3.8以降では、リスト内包表記で代入式(別名walrus演算子)を使用できます。例:

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

代入式は、変数に値を割り当てることができますし、同じ表現でそれを返します。したがって、式

b := a + (a := b)

実行と同等

a, b = b, a + b

の値を返しますb


0

私がPythonを学習するときに使用したチュートリアルの15分後、3つの入力数(最初のフィボナッチ数、2番目の数、およびシーケンスを停止する数)からフィボナッチ数列を計算するプログラムを作成するよう読者に求めました。チュートリアルは変数if / thensのみをカバーしており、その時点までループします。まだ機能はありません。私は次のコードを思いつきました:

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

ご覧のとおり、それは本当に非効率的ですが、機能します。


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())ここでは必要ありません。int(input())ケースの方がいいと思います。
GingerPlusPlus 2014年

0

http://projecteuler.net/problem=2を通過するだけで、これは私の考えでした

# 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

多分これは役立つでしょう

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

0

古典的なフィボナッチシーケンスに基づいており、ワンライナーのために

インデックスの数だけが必要な場合は、reduceを使用できます(reduceがこれに最適ではない場合でも、良い演習になります)

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]

完全な配列を取得するには、or(r.pop(0)and 0)を削除するだけです

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

0

これはどう?期待される出力を生成するために以前の結果の初期仕様を要求するため、他の提案ほど豪華ではないと思いますが、私は非常に読みやすいオプションだと感じています。つまり、結果と以前の結果を提供するだけです。再帰。

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

出力は次のとおりです。

0
1
1
2
3
5
8
13
21
34
done


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

フィボナッチシーケンスでメモ化がどのように機能するかについての詳細な説明。

# 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

私はこの問題を解決するために再帰的な関数を避けようとしていたので、反復的なアプローチをとりました。私はもともとメモ化された再帰関数を実行していましたが、最大の再帰深度に達し続けました。厳密なメモリ目標も設定していたので、ループプロセス中は常に2〜3個の値のみを配列に保持するので、配列をできるだけ小さく保つことができます。

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

600万個のフィボナッチ数列を取得するには、私のマシンで約282秒かかりますが、600kのフィボナッチ数列はわずか2.8秒です。覚えていても、再帰関数でこのような大きなフィボナッチ数を取得することはできませんでした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.