Як записати послідовність Фібоначчі?


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 (яка була закрита через те, що вона була дублікатом - /programming/504193/how-to-write-the-fibach-sequence-in-python-part-ii ), що я необхідно передати startNumber і endNumber через генератор, використовуючи цикл while. Чи може хтось, будь ласка, вказати мені в напрямку, як це зробити? Будь-яка допомога вітається.


Я програміст, що навчається, і я трохи зіткнувся. Мене просять написати програму, яка буде обчислювати та відображати послідовність Фібоначчі за введеним користувачем початковим номером та кінцевим номером (тобто. StartNumber = 20 endNumber = 100, і вона відображатиме лише числа між цим діапазоном). Трюк полягає в тому, щоб використовувати його інклюзивно (що я не знаю, як зробити в Python? - Я припускаю, що це означає використовувати інклюзивний діапазон?).

У мене поки що немає фактичного кодування, а скоріше:

  • Напишіть формулу послідовності Fib до нескінченності
  • Відобразити startNumber до endNumber лише з послідовності Fib.

Я поняття не маю, з чого почати, і я прошу ідеї чи розуміння, як це написати. Я також намагався написати форум форумів послідовностей Fib, але я також втрачаю на цьому.

Відповіді:


257

Є багато відомостей про послідовність Фібоначчі у вікіпедії та вольфрамі . Набагато більше, ніж вам може знадобитися. У будь-якому випадку, це добре навчитися використовувати ці ресурси, щоб знайти (швидко, якщо можливо) те, що вам потрібно.

Напишіть формулу послідовності Fib до нескінченності

У математиці він подається в рекурсивній формі:

поле з wikipedia

У програмуванні нескінченності не існує. Ви можете використовувати рекурсивну форму, що переводить математичну форму безпосередньо на вашу мову, наприклад, в Python це стає:

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

Спробуйте це на своїй улюбленій мові і переконаєтесь, що ця форма вимагає багато часу, оскільки п росте більше. Насправді, це 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))

Інший спосіб зробити це - слідуючи визначенню (з wikipedia ):

Перше число послідовності дорівнює 0, друге число дорівнює 1, і кожне наступне число дорівнює сумі попередніх двох чисел самої послідовності, виводячи послідовність 0, 1, 1, 2, 3, 5, 8 тощо.

Якщо ваша мова підтримує ітератори, ви можете зробити щось на кшталт:

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

Відобразити startNumber до endNumber лише з послідовності Fib.

Як тільки ви дізнаєтеся, як генерувати числа Фібоначчі, вам просто доведеться пройти чисел і перевірити, чи вони перевіряють задані умови.

Припустимо, тепер ви написали af (n), який повертає 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

Мій натяк - навчитися читати те, що потрібно. Проект Euler (Google для нього) навчить вас це робити: P Удачі та веселощів!


1
Вам потрібно використовувати цикл час, а не карту. Спробуйте розібратися в цьому самостійно, а потім поверніться з кодом, якщо ви не можете цього зробити. Я не лінуюся (код коротший, ніж цей коментар). Я роблю це для вас, спробуйте це з підказкою "в той час";) Якщо у вас проблеми з цим повертайтеся знову;)
Андреа Амбу

Я повернувся, лол. Я позбувся функції карти (діапазону) і використовую лише функцію діапазону (startNumber, endNumber). Тепер у мене проблема полягає в тому, де використовувати оператор while. Я намагаюсь на початку функції, але, звичайно, є помилки, зроблені рядками помилок. Куди мені це покласти? Thx
SD.

Спробуйте зробити вручну приклад вводу-виводу вашої програми (з невеликим діапазоном). Спробуйте потім з’ясувати, де ваша програма не так. Спробуйте перетворити "метод від руки" в код. Це для вправ, для навчання. Я міг би викласти два рядки коду, але не думаю, що ви з них нічого дізнаєтесь.
Андреа Амбу

1
Ми повинні використовувати int(((1+sqrt(5))**n-(1-sqrt(5))**n)/(2**n*sqrt(5)))якісь ідеї? @AndreaAmbu
lord63. j

3
@ lord63.j, ви повинні використовувати цю формулу лише в тому випадку, якщо ви знаєте, що вона починає відхилятися від фактичного значення, коли nвище 70, і вибухає з, OverflowError коли nтрохи вище 600. Інші підходи можуть обробляти n1000 або більше, не дмухаючи або втрачає точність.
cdlane

66

Ефективний пітонічний генератор послідовності Фібоначчі

Я знайшов це питання під час спроби отримати найкоротшу пітонічну генерацію цієї послідовності (пізніше зрозумівши, що я бачив подібне у пропозиції щодо розширення 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 на модулях, навіть використовуючи змінні aі b, яку я зараз пам’ятаю, бачив перед тим, як писати цю відповідь. Але я думаю, що ця відповідь демонструє краще використання мови.)

Рекурсивно визначена реалізація

Інтернет Енциклопедія цілочислових послідовностей визначає послідовність Фібоначчі рекурсивно

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 може досягати 100 мільйонів, хоча для цього використовується 8 Гб пам'яті мого ноутбука:

> length $ take 100000000 fib 
100000000

Споживаючи ітератор, щоб отримати номер n-го значення

Коментолог запитує:

Питання для функції Fib (), заснованої на ітераторі: що робити, якщо ви хочете отримати n-й, наприклад, 10-й номер фіб?

Документація 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 - дійсний ключ? Док каже: "Якщо ключ є у словнику, поверніть його значення. Якщо ні, вставте ключ зі значенням за замовчуванням та поверніть за замовчуванням. За замовчуванням до" Немає ". Що я пропускаю?
бінітб

@binithb вираження всередині setdefaultвиклику оцінюється раніше, ніж setdefault є.
Аарон Холл

23

Чому б просто не зробити наступне?

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

21

Ідея послідовності Фібоначчі показана в наступному коді Python:

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

Це означає, що fib - це функція, яка може виконувати одну з трьох речей. Він визначає 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 (3) не можна обчислити без обчислення fib (2), що обчислюється знанням визначень fib (1) та fib (0). Сам виклик функції, як функція напруженості, називається рекурсією, і це важлива тема програмування.

Це звучить як домашнє завдання, тому я не збираюся робити для вас початок / кінець. Python - це надзвичайно виразна мова для цього, тому це має мати сенс, якщо ви розумієте математику, і, сподіваємось, навчите вас про рекурсію. Удачі!

Редагувати: Однією з потенційних критик мого коду є те, що він не використовує надзвичайно зручний вихід функції Python, завдяки чому функція fib (n) значно скорочується. Мій приклад є трохи більш загальним, оскільки не так багато мов поза Python насправді мають вихід.


Це не проблема домашнього завдання, але я дякую за відповідь! Я розумію, що мені потрібно зробити, але запустити його та реалізувати - це те, на чому я зараз застряг (особливо з використанням значень введення користувача). Чи можете ви дати деяке розуміння цього? Я продовжую отримувати <функцію fib при 0x0141FAF0> помилці.
СД.

Я розумію, що ви дуже намагаєтесь реалізувати програму, яка може перевищувати ваші поточні можливості. Якщо мені написати більше коду, вам не допоможе. Вам слід спробувати зламати з моїм кодом, поки він не працює, і прочитати більше навчальних посібників Python. Пробіл може бути проблемою, але я не знаю цієї помилки.
Джеймс Томпсон

Я розумію. Чи є якась інша ідея, яку, на вашу думку, я можу пропасти? Я розумію, якщо ви не можете допомогти. Я дякую вам за ваш час.
СД.

Ваша помилка <функція при 0x0141FAF0> може бути результатом вимови "fib" (яка стосується самої функції) замість "fib ()", яка викликатиме функцію. Удачі.
Ків

8
Майте на увазі, що цей наївний рекурсивний метод обчислення чисел Фібоначчі може швидко переграти стек (не сайт). Для практичних цілей генеруйте ітераційно або використовуйте якусь пам ятку або щось подібне.
Девід Торнлі

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)

Цей обчислює X ^ n у поліноміальному кільці Z [X] / (X ^ 2 - X - 1), використовуючи експоненцію шляхом квадратування. Результатом цього обчислення є многочлен 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; з цим ефективно n -= 1працювати потрібно, і це також не працює n = 0. У будь-якому випадку, мені дуже допоможе, якби було додано багато контексту, щоб пояснити, як це працює, особливо перша техніка. Я бачу, у вас є повідомлення на сторінці paulhankin.github.io/Fibach
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). Ми обчислюємо o 'потужність Q з експонентом n-1, а потім беремо елемент m00, який є Fn + 1, що в показника потужності n-1 - це саме п яте число, яке ми бажали.

Після того, як у вас буде функція швидкої напруги, ви можете перейти від стартового номера та номера кінця, щоб отримати частину послідовності, яка вас цікавить.

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

звичайно спочатку проведіть деяку перевірку на початку та в кінці, щоб переконатися, що вони можуть сформувати дійсний діапазон.

Я знаю, що це питання 8 років, але мені було весело відповісти. :)


3

Послідовність Фібоначчі: 1, 1, 2, 3, 5, 8, ....

Тобто f(1) = 1, f(2) = 1, f(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 і зменшення - це 2 з трьох найпотужніших функцій python. Тут карта використовується просто для повторення "n-2" разів. a [-2:] отримає два останні елементи масиву. a.append (x + y) додасть два останні елементи та додасть до масиву


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! напруженість (10000000000000000000000000000000000000000000000000000000000000000000000000000000000000) відповідає майже миттєво
Ганс

6
Якось у цьому сумніваюся.
Ланару

Як щодо запуску списку як [0, 1] (тобто List.append (0); List.append (1)), щоб уникнути команди видалення після іншого? ... і число лінійки слід краще індексувати, оскільки фігура (10) повертає цифри напруги нижче 10, а не десятих.
СеФ

1

Гаразд .. після того, як втомився згадувати всі тривалі відповіді, тепер знайдіть поданий нижче сорт & солодкий, досить прямий шлях для впровадження Фібоначчі в пітон. Ви можете покращити його так, як вам захочеться, отримавши аргумент або отримавши введення користувача… або змінивши обмеження на 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

код повинен друкувати b, а не друкувати c

вихід: 1,1,2,3,5 ....


1

Використання для циклу та друку тільки результату

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, 43349377777, 69349, 7349, 69349, 69349, 69349, 69349, 69349, 69349, 69349, 69349, 69349, 69349, 69349, 69349, 69349, 69349, 693, 69349, 693, 69349, 694, 694, 693, 694, 694, 695, 693, 693, 693, 693, 694, 693, 693, 694, 693, 695, 750,,,,, , 12586269025, 20365011074, 32951280099, 53316291173, 86267571272, 139583862445, 225851433717, 365435296162, 591286729879, 956722026041, 1548008755920, 2504730781961, 405275955755, 275, 275,,

час роботи: 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

1

Зробити це можна наступним чином.

n = 0

цифри = [0]

для i в діапазоні (0,11):
    друкувати n,
    numbers.append (n)
    prev = числа [-2]
    якщо n == 0:
        n = 1
    ще:
        n = n + prev

1

Для розваги, в Python 3.8+ ви можете використовувати вираз призначення (він же оператор моржів) у розумінні списку, наприклад:

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

Через 15 хвилин підручник, який я використовував під час вивчення Python, він попросив читача написати програму, яка обчислила б послідовність Фібоначчі з 3-х вхідних чисел (перше число Фібоначчі, друге число та число, на якому зупиняти послідовність). Навчальний посібник охоплював лише змінні, якщо / 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

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

ґрунтуючись на класичній послідовності фільонок і просто заради однолінійки

якщо вам просто потрібен номер індексу, ви можете використовувати зменшення (навіть якщо зменшити це не найкраще для цього, це може бути хорошою вправою)

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]

і щоб отримати повний масив, просто видаліть або (r.pop (0) і 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

Більш детальне пояснення того, як Memoization працює для послідовності Фібоначчі.

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

Отримання 6-мільйонного числа зайнятих на моїй машині займає близько 282 секунд, тоді як поле 600k займає лише 2,8 секунди. Мені не вдалося отримати такі великі цифри з рекурсивною функцією, навіть запам'ятовувану.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.