在SmartPy中,递归是通过允许函数在其自己的定义中调用自身来实现的。在处理可以分解为更小的、相同的子问题时,这种方法非常有用。视图(view)是一个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):
"""Contract with a recursing view to compute the sum of fibonacci numbers."""
@sp.onchain_view()
def fibonacci(self, n):
"""Return the sum of fibonacci numbers until n.
Args:
n (sp.int): number of fibonacci numbers to sum.
Return:
(sp.int): the sum of fibonacci numbers
"""
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("fibonacci", sp.self_address(), n - 2, int).unwrap_some()
return n1 + n2
if "templates" not in __name__:
@sp.add_test(name="FibonacciView basic scenario", is_default=True)
def basic_scenario():
sc = sp.test_scenario(main)
sc.h1("Basic scenario.")
sc.h2("Origination.")
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-1
和n-2
的fibonacci
函数,然后将结果相加来计算第n个斐波那契数。这符合定义斐波那契数列的递归关系。sp.view
调用创建了对fibonacci
函数本身的递归调用。
我们继续看看测试部分。
在测试函数basic_scenario
中,创建一个新的FibonacciView
合约实例,将其添加到本场景中,然后使用sc.verify
检查第8个斐波那契数是否为21,若是,则斐波那契数列是正确的。
运行代码:
打开SmartPy IDE。
将我们提供的代码复制并粘贴到编辑器中。
单击“Run”按钮,在IDE右侧会显示正在执行的测试场景。你可以看到正在执行的操作和验证的检查。
在这节课中,我们介绍了很多高级概念,包括递归的基础知识、它在编程中的使用、SmartPy中的递归视图,以及递归在斐波那契数列中的应用。我们还探讨了SmartPy中的一个工作代码示例,还学习了如何在SmartPy IDE中运行和验证此代码。
在SmartPy中,递归是通过允许函数在其自己的定义中调用自身来实现的。在处理可以分解为更小的、相同的子问题时,这种方法非常有用。视图(view)是一个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):
"""Contract with a recursing view to compute the sum of fibonacci numbers."""
@sp.onchain_view()
def fibonacci(self, n):
"""Return the sum of fibonacci numbers until n.
Args:
n (sp.int): number of fibonacci numbers to sum.
Return:
(sp.int): the sum of fibonacci numbers
"""
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("fibonacci", sp.self_address(), n - 2, int).unwrap_some()
return n1 + n2
if "templates" not in __name__:
@sp.add_test(name="FibonacciView basic scenario", is_default=True)
def basic_scenario():
sc = sp.test_scenario(main)
sc.h1("Basic scenario.")
sc.h2("Origination.")
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-1
和n-2
的fibonacci
函数,然后将结果相加来计算第n个斐波那契数。这符合定义斐波那契数列的递归关系。sp.view
调用创建了对fibonacci
函数本身的递归调用。
我们继续看看测试部分。
在测试函数basic_scenario
中,创建一个新的FibonacciView
合约实例,将其添加到本场景中,然后使用sc.verify
检查第8个斐波那契数是否为21,若是,则斐波那契数列是正确的。
运行代码:
打开SmartPy IDE。
将我们提供的代码复制并粘贴到编辑器中。
单击“Run”按钮,在IDE右侧会显示正在执行的测试场景。你可以看到正在执行的操作和验证的检查。
在这节课中,我们介绍了很多高级概念,包括递归的基础知识、它在编程中的使用、SmartPy中的递归视图,以及递归在斐波那契数列中的应用。我们还探讨了SmartPy中的一个工作代码示例,还学习了如何在SmartPy IDE中运行和验证此代码。