У світі інформатики рекурсія — це метод, коли рішення проблеми залежить від менших екземплярів тієї самої проблеми. Це процес, у якому функція викликає сама себе як підпрограму. Це дозволяє викликати функцію з меншою кількістю аргументів, зменшуючи кількість інформації про стан, яку має підтримувати функція, і забезпечуючи дуже елегантні та лаконічні засоби вираження рішень деяких типів проблем. Рекурсія часто розглядається як складна концепція для початківців. Однак, якщо його правильно зрозуміти, він може бути надзвичайно потужним інструментом в арсеналі програміста. Це може допомогти створити більш чистий і стислий код, і часто може використовуватися для вирішення складних проблем за допомогою простих, елегантних рішень.
У цьому уроці ми застосуємо рекурсію до послідовності Фібоначчі, яка є рядом чисел, де число є додаванням двох останніх чисел, тобто 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 і так далі. Послідовність починається з 0, тому n-те число є сумою (n-1)-го та (n-2)-го чисел.
У SmartPy рекурсія реалізована, дозволяючи функції викликати саму себе у своєму власному визначенні. Цей метод надзвичайно корисний, коли маєте справу з проблемами, які можна розбити на більш дрібні ідентичні підпроблеми. Рекурсивне подання в SmartPy — це по суті подання, яке використовує рекурсію. Представлення — це функція SmartPy, яка не змінює сховище контракту, але може читати з нього. Коли ми говоримо про рекурсивний перегляд, ми маємо на увазі функцію перегляду, яка викликає сама себе під час свого виконання.
Послідовність Фібоначчі - це набір чисел, де кожне число є сумою двох попередніх, починаючи з 0 і 1. Ця послідовність, хоч і проста, забезпечує чудову основу для розуміння рекурсії через її рекурсивну природу.
Послідовність Фібоначчі визначається рекурентним співвідношенням:
SCSS
F(n) = F(n-1) + F(n-2)
З початковими умовами F(0) = 0 і F(1) = 1. Це означає, що для отримання n
-го числа в послідовності Фібоначчі ми додаємо (n-1
)-е та (n-2
)-е числа. Саме ця рекурсивна природа робить послідовність Фібоначчі ідеальною для розуміння рекурсії. Тепер, коли ми краще розуміємо рекурсію та її застосування до послідовності Фібоначчі, давайте зануримося в код SmartPy, який реалізує рекурсивне подання для обчислення послідовності Фібоначчі.
Наведений код SmartPy визначає контракт FibonacciView
, який обчислює послідовність Фібоначчі за допомогою рекурсивного перегляду. Це чудовий приклад, щоб зрозуміти, як рекурсивні функції створюються та використовуються в SmartPy.
Python
import smartpy as sp
@sp.module
def main():
class FibonacciView(sp.Contract):
"""Контракт із рекурсивним поданням для обчислення суми чисел Фібоначчі."""
@sp.onchain_view()
def fibonacci(self, n):
"""Повертає суму чисел Фібоначчі до n.
Аргументи:
n (sp.int): кількість чисел Фібоначчі для підсумовування.
Повернення:
(sp.int): сума чисел Фібоначчі
"""
sp.cast(n, int)
if n < 2:
return n
else:
n1 = sp.view("fibonacci", sp.self_address(), n - 1, int).unwrap_some()
n2 = sp.view("фібоначчі", sp.self_address(), n - 2, int).unwrap_some()
повернути n1 + n2
, якщо "шаблони" не в __name__:
@sp.add_test(name="базовий сценарій FibonacciView", is_default=True)
def basic_scenario():
sc = sp.test_scenario(main)
sc.h1("Базовий сценарій.")
sc.h2("Походження.")
c1 = main.FibonacciView()
sc += c1
sc.verify(c1.fibonacci(8) == 21)
Цей контракт FibonacciView
має функцію рекурсивного перегляду fibonacci
, яка повертає n-е число Фібоначчі.
Функція прикрашена @sp.onchain_view()
, що вказує на те, що це операція лише для читання в сховищі контракту. Ця функція приймає ціле число n
як аргумент, що представляє позицію в послідовності Фібоначчі, яку ми хочемо отримати.
Усередині функції ми спочатку перетворюємо n
на ціле число для безпеки. Далі йде рекурсивна частина функції. Якщо n
менше 2, ми просто повертаємо n
, оскільки перші два числа послідовності Фібоначчі дорівнюють 0 і 1. Якщо n
більше або дорівнює 2, ми обчислюємо n-е число Фібоначчі, рекурсивно викликаючи функцію fibonacci
для n-1
і n-2
, а потім додаючи результати. Це відповідає рекурентному відношенню, що визначає послідовність Фібоначчі. Виклики sp.view
створюють рекурсивні виклики самої функції fibonacci
.
Використання циклу для підвищення ефективності
Хоча рекурсія є цінною концепцією для розуміння, важливо зазначити, що вона може бути менш ефективною та вимагати більше обчислювальних ресурсів, особливо при роботі з великими числами. Щоб уникнути таких проблем, як переповнення стека, більш ефективним підходом було б використовувати цикл для обчислення послідовності Фібоначчі та зберігати розраховані числа Фібоначчі в окремому контракті.
Ось приклад високого рівня того, як ви можете модифікувати контракт FibonacciView для використання циклу:
Цей модифікований контракт, FibonacciCalculator, використовує цикл для ефективного обчислення чисел Фібоначчі та зберігає їх у сховищі контракту. Потім ви можете викликати точку входу calculate_fibonacci, щоб отримати n-е число Фібоначчі.
Цей підхід є більш ресурсозберігаючим і підходить для більших значень n.
Python
@sp.moduledef main():
клас FibonacciCalculator(sp.Contract):
"""Контракт для ефективного обчислення послідовності Фібоначчі."""def __init__(self):
self.init(storage=sp.map(tkey=sp.TInt, tvalue=sp.TInt).set(0, 0).set(1, 1))
@sp.entry_pointdef calculate_fibonacci(self, n):
sp.verify(n >= 0, message="n має бути невід’ємним")
storage = self.data
for i in range(2, n + 1):
next_fib = storage[i - 1] + storage[i - 2]
storage = storage.set(i, next_fib)
sp.result(storage[n])
Продовжимо розділ тестування.
У тестовій функції basic_scenario
ми створюємо новий екземпляр контракту FibonacciView
, додаємо його до нашого сценарію, а потім використовуємо sc.verify
, щоб перевірити, що 8-е число Фібоначчі дорівнює 21, що вірно для послідовності Фібоначчі.
Щоб запустити код:
Відкрийте IDE SmartPy.
Скопіюйте та вставте наданий код у редактор.
Натисніть на кнопку «Виконати». Ви повинні побачити тестовий сценарій, який виконується в правій частині IDE. Ви побачите, як виконуються операції та перевіряються перевірки.
Цей урок охопив багато питань. Ми перейшли від основ рекурсії та того, як вона використовується в програмуванні, до рекурсивних представлень у SmartPy і навіть застосували ці концепції до послідовності Фібоначчі. Ми також дослідили приклад робочого коду в SmartPy, і ви дізналися, як запустити та перевірити цей код у SmartPy IDE.
У світі інформатики рекурсія — це метод, коли рішення проблеми залежить від менших екземплярів тієї самої проблеми. Це процес, у якому функція викликає сама себе як підпрограму. Це дозволяє викликати функцію з меншою кількістю аргументів, зменшуючи кількість інформації про стан, яку має підтримувати функція, і забезпечуючи дуже елегантні та лаконічні засоби вираження рішень деяких типів проблем. Рекурсія часто розглядається як складна концепція для початківців. Однак, якщо його правильно зрозуміти, він може бути надзвичайно потужним інструментом в арсеналі програміста. Це може допомогти створити більш чистий і стислий код, і часто може використовуватися для вирішення складних проблем за допомогою простих, елегантних рішень.
У цьому уроці ми застосуємо рекурсію до послідовності Фібоначчі, яка є рядом чисел, де число є додаванням двох останніх чисел, тобто 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 і так далі. Послідовність починається з 0, тому n-те число є сумою (n-1)-го та (n-2)-го чисел.
У SmartPy рекурсія реалізована, дозволяючи функції викликати саму себе у своєму власному визначенні. Цей метод надзвичайно корисний, коли маєте справу з проблемами, які можна розбити на більш дрібні ідентичні підпроблеми. Рекурсивне подання в SmartPy — це по суті подання, яке використовує рекурсію. Представлення — це функція SmartPy, яка не змінює сховище контракту, але може читати з нього. Коли ми говоримо про рекурсивний перегляд, ми маємо на увазі функцію перегляду, яка викликає сама себе під час свого виконання.
Послідовність Фібоначчі - це набір чисел, де кожне число є сумою двох попередніх, починаючи з 0 і 1. Ця послідовність, хоч і проста, забезпечує чудову основу для розуміння рекурсії через її рекурсивну природу.
Послідовність Фібоначчі визначається рекурентним співвідношенням:
SCSS
F(n) = F(n-1) + F(n-2)
З початковими умовами F(0) = 0 і F(1) = 1. Це означає, що для отримання n
-го числа в послідовності Фібоначчі ми додаємо (n-1
)-е та (n-2
)-е числа. Саме ця рекурсивна природа робить послідовність Фібоначчі ідеальною для розуміння рекурсії. Тепер, коли ми краще розуміємо рекурсію та її застосування до послідовності Фібоначчі, давайте зануримося в код SmartPy, який реалізує рекурсивне подання для обчислення послідовності Фібоначчі.
Наведений код SmartPy визначає контракт FibonacciView
, який обчислює послідовність Фібоначчі за допомогою рекурсивного перегляду. Це чудовий приклад, щоб зрозуміти, як рекурсивні функції створюються та використовуються в SmartPy.
Python
import smartpy as sp
@sp.module
def main():
class FibonacciView(sp.Contract):
"""Контракт із рекурсивним поданням для обчислення суми чисел Фібоначчі."""
@sp.onchain_view()
def fibonacci(self, n):
"""Повертає суму чисел Фібоначчі до n.
Аргументи:
n (sp.int): кількість чисел Фібоначчі для підсумовування.
Повернення:
(sp.int): сума чисел Фібоначчі
"""
sp.cast(n, int)
if n < 2:
return n
else:
n1 = sp.view("fibonacci", sp.self_address(), n - 1, int).unwrap_some()
n2 = sp.view("фібоначчі", sp.self_address(), n - 2, int).unwrap_some()
повернути n1 + n2
, якщо "шаблони" не в __name__:
@sp.add_test(name="базовий сценарій FibonacciView", is_default=True)
def basic_scenario():
sc = sp.test_scenario(main)
sc.h1("Базовий сценарій.")
sc.h2("Походження.")
c1 = main.FibonacciView()
sc += c1
sc.verify(c1.fibonacci(8) == 21)
Цей контракт FibonacciView
має функцію рекурсивного перегляду fibonacci
, яка повертає n-е число Фібоначчі.
Функція прикрашена @sp.onchain_view()
, що вказує на те, що це операція лише для читання в сховищі контракту. Ця функція приймає ціле число n
як аргумент, що представляє позицію в послідовності Фібоначчі, яку ми хочемо отримати.
Усередині функції ми спочатку перетворюємо n
на ціле число для безпеки. Далі йде рекурсивна частина функції. Якщо n
менше 2, ми просто повертаємо n
, оскільки перші два числа послідовності Фібоначчі дорівнюють 0 і 1. Якщо n
більше або дорівнює 2, ми обчислюємо n-е число Фібоначчі, рекурсивно викликаючи функцію fibonacci
для n-1
і n-2
, а потім додаючи результати. Це відповідає рекурентному відношенню, що визначає послідовність Фібоначчі. Виклики sp.view
створюють рекурсивні виклики самої функції fibonacci
.
Використання циклу для підвищення ефективності
Хоча рекурсія є цінною концепцією для розуміння, важливо зазначити, що вона може бути менш ефективною та вимагати більше обчислювальних ресурсів, особливо при роботі з великими числами. Щоб уникнути таких проблем, як переповнення стека, більш ефективним підходом було б використовувати цикл для обчислення послідовності Фібоначчі та зберігати розраховані числа Фібоначчі в окремому контракті.
Ось приклад високого рівня того, як ви можете модифікувати контракт FibonacciView для використання циклу:
Цей модифікований контракт, FibonacciCalculator, використовує цикл для ефективного обчислення чисел Фібоначчі та зберігає їх у сховищі контракту. Потім ви можете викликати точку входу calculate_fibonacci, щоб отримати n-е число Фібоначчі.
Цей підхід є більш ресурсозберігаючим і підходить для більших значень n.
Python
@sp.moduledef main():
клас FibonacciCalculator(sp.Contract):
"""Контракт для ефективного обчислення послідовності Фібоначчі."""def __init__(self):
self.init(storage=sp.map(tkey=sp.TInt, tvalue=sp.TInt).set(0, 0).set(1, 1))
@sp.entry_pointdef calculate_fibonacci(self, n):
sp.verify(n >= 0, message="n має бути невід’ємним")
storage = self.data
for i in range(2, n + 1):
next_fib = storage[i - 1] + storage[i - 2]
storage = storage.set(i, next_fib)
sp.result(storage[n])
Продовжимо розділ тестування.
У тестовій функції basic_scenario
ми створюємо новий екземпляр контракту FibonacciView
, додаємо його до нашого сценарію, а потім використовуємо sc.verify
, щоб перевірити, що 8-е число Фібоначчі дорівнює 21, що вірно для послідовності Фібоначчі.
Щоб запустити код:
Відкрийте IDE SmartPy.
Скопіюйте та вставте наданий код у редактор.
Натисніть на кнопку «Виконати». Ви повинні побачити тестовий сценарій, який виконується в правій частині IDE. Ви побачите, як виконуються операції та перевіряються перевірки.
Цей урок охопив багато питань. Ми перейшли від основ рекурсії та того, як вона використовується в програмуванні, до рекурсивних представлень у SmartPy і навіть застосували ці концепції до послідовності Фібоначчі. Ми також дослідили приклад робочого коду в SmartPy, і ви дізналися, як запустити та перевірити цей код у SmartPy IDE.