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


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.