コンピュータサイエンスの世界では、再帰は、問題の解決策が同じ問題のより小さなインスタンスに依存する方法です。 これは、関数が自分自身をサブルーチンとして呼び出すプロセスです。 これにより、より少ない引数で関数を呼び出すことができ、関数によって維持される必要がある状態情報の量が減り、ある種の問題の解決策を表現するための非常にエレガントで簡潔な手段が提供されます。 再帰は、初心者が理解するのが難しい概念と見なされることがよくあります。 しかし、正しく理解すれば、プログラマーの武器庫の中で非常に強力なツールになる可能性があります。 これは、よりクリーンで簡潔なコードを作成するのに役立ち、多くの場合、シンプルでエレガントなソリューションで複雑な問題を解決するために使用できます。
このレッスンでは、最後の2つの数値(0、1、1、2、3、5、8、13、21、34など)を加算した一連の数値であるフィボナッチ数列に再帰を適用します。 シーケンスは 0 から始まるため、n 番目の数値は (n-1) 番目の数値と (n-2) 番目の数値の合計です。
SmartPy では、関数が独自の定義内で自分自身を呼び出せるようにすることで、再帰が実装されます。 この方法は、より小さく同一のサブ問題に分解できる問題を扱う場合に非常に役立ちます。 SmartPy の再帰ビューは、基本的に再帰を使用するビューです。 ビューは、コントラクト ストレージを変更しないが、そこから読み取ることができる SmartPy 関数です。 再帰的ビューとは、実行中に自分自身を呼び出すビュー関数を意味します。
フィボナッチ数列は、各数値が0と1から始まる前の2つの数値の合計である数値のセットです。 このシーケンスは単純ですが、再帰的な性質のため、再帰を理解するための優れた基盤を提供します。
フィボナッチ数列は、漸化関係によって定義されます。
SCSSの
F(n) = F(n-1) + F(n-2)
初期条件は F(0) = 0、F(1) = 1 です。 これは、フィボナッチ数列の-番目の数を取得するn
ために、()番目の数と(n-1
n-2
)番目の数を追加することを意味します。この再帰的な性質こそが、フィボナッチ数列が再帰を理解するのに完璧に適している理由です。 再帰とそれがフィボナッチ数列にどのように適用されるかについて理解が深まったところで、フィボナッチ数列を計算するための再帰ビューを実装する SmartPy コードに飛び込んでみましょう。
与えられた SmartPy コードは、 FibonacciView
再帰ビューを使用してフィボナッチ数列を計算するコントラクト を定義します。 これは、再帰関数が SmartPy でどのように作成され、使用されるかを理解するための優れた例です。
ニシキヘビ
SmartPy を SP としてインポートする
@sp.モジュール
デフmain():
class FibonacciView(sp.契約):
"""フィボナッチ数の合計を計算するための再帰ビューとの契約。 @sp.onchain_view()を呼び出します。
defフィボナッチ(self、n):
"""nまでのフィボナッチ数の和を返します。 引数:
n(sp.int):合計するフィボナッチ数。 帰る:
(sp.int):フィボナッチ数の和
"""
sp.cast(n, int)
n < 2 の場合:
nを返す
然も無くば:
n1 = sp.view("フィボナッチ", 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="フィボナッチビューの基本シナリオ", is_default=True)
def basic_scenario():
sc = sp.test_scenario(メイン) sc.h1("基本シナリオ") sc.h2("オリジネーション") C1 = メイン。フィボナッチビュー()
sc + = c1の
sc.verify(c1.フィボナッチ(8) == 21)
この FibonacciView
コントラクトには、 fibonacci
n 番目のフィボナッチ数を返す再帰ビュー関数があります。
この関数は で修飾 @sp.onchain_view()
されており、これがコントラクトのストレージに対する読み取り専用操作であることを示します。 この関数は、取得するフィボナッチ数列内の位置を表す整数 n
を引数として取ります。
関数内では、安全のために最初に整数にキャスト n
します。 関数の再帰的な部分が次に来ます。 が 2 より小さい場合 n
、フィボナッチ数列の最初の 2 つの数値は 0 と 1 であるため、単純に戻ります n
。 が 2 以上の場合n
、と n-2
のn-1
関数を再帰的に呼び出しfibonacci
、結果を加算することにより、n 番目のフィボナッチ数を計算します。これは、フィボナッチ数列を定義する漸化関係に相当します。 呼び出しは sp.view
、 fibonacci
関数自体に対するこれらの再帰的な呼び出しを作成します。
効率化のためのループの使用
再帰は理解するための貴重な概念ですが、特に大きな数を扱う場合は、効率が悪く、より多くの計算リソースが必要になる可能性があることに注意することが重要です。 スタックオーバーフローなどの問題を回避するには、ループを使用してフィボナッチ数列を計算し、計算されたフィボナッチ数を別の契約に格納する方が効率的なアプローチです。以下は、ループを使用するようにFibonacciView契約を変更する方法の高レベルの例です。
この修正された契約であるFibonacciCalculatorは、ループを使用してフィボナッチ数を効率的に計算し、契約のストレージに保存します。 次に、calculate_fibonacciエントリポイントを呼び出して、n番目のフィボナッチ数を取得できます。このアプローチはリソース効率が高く、n の大きな値に適しています。
ニシキヘビ
@sp.moduledef main()を使用します。
class FibonacciCalculator(sp.契約):
"""フィボナッチ数列を効率的に計算する契約。"""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 は負でない必要があります")
ストレージ = self.data
範囲(2、n + 1)のiの場合:
next_fib = storage[i - 1] + storage[i - 2]
ストレージ= storage.set(i、 next_fib)
sp.result(ストレージ[n])
テストのセクションに進みましょう。
テスト関数 basic_scenario
では、コントラクトの新しい FibonacciView
インスタンスを作成し、それをシナリオに追加してから、8 sc.verify
番目のフィボナッチ数がフィボナッチ数列に当てはまる21であることを確認します。
コードを実行するには、次のようにします。
SmartPy IDE を開きます。
提供されたコードをコピーしてエディターに貼り付けます。
「実行」ボタンをクリックします。 IDEの右側にテストシナリオが実行されているのが見えるはずです。 実行中の操作と検証中のチェックが表示されます。
このレッスンでは、多くの分野をカバーしています。 再帰の基本とプログラミングでの使用方法から、SmartPy の再帰ビュー、さらにはこれらの概念をフィボナッチ数列に適用する方法まで説明しました。 また、SmartPy で実際に動作するコード例も確認し、SmartPy IDE でこのコードを実行して検証する方法も学習しました。
コンピュータサイエンスの世界では、再帰は、問題の解決策が同じ問題のより小さなインスタンスに依存する方法です。 これは、関数が自分自身をサブルーチンとして呼び出すプロセスです。 これにより、より少ない引数で関数を呼び出すことができ、関数によって維持される必要がある状態情報の量が減り、ある種の問題の解決策を表現するための非常にエレガントで簡潔な手段が提供されます。 再帰は、初心者が理解するのが難しい概念と見なされることがよくあります。 しかし、正しく理解すれば、プログラマーの武器庫の中で非常に強力なツールになる可能性があります。 これは、よりクリーンで簡潔なコードを作成するのに役立ち、多くの場合、シンプルでエレガントなソリューションで複雑な問題を解決するために使用できます。
このレッスンでは、最後の2つの数値(0、1、1、2、3、5、8、13、21、34など)を加算した一連の数値であるフィボナッチ数列に再帰を適用します。 シーケンスは 0 から始まるため、n 番目の数値は (n-1) 番目の数値と (n-2) 番目の数値の合計です。
SmartPy では、関数が独自の定義内で自分自身を呼び出せるようにすることで、再帰が実装されます。 この方法は、より小さく同一のサブ問題に分解できる問題を扱う場合に非常に役立ちます。 SmartPy の再帰ビューは、基本的に再帰を使用するビューです。 ビューは、コントラクト ストレージを変更しないが、そこから読み取ることができる SmartPy 関数です。 再帰的ビューとは、実行中に自分自身を呼び出すビュー関数を意味します。
フィボナッチ数列は、各数値が0と1から始まる前の2つの数値の合計である数値のセットです。 このシーケンスは単純ですが、再帰的な性質のため、再帰を理解するための優れた基盤を提供します。
フィボナッチ数列は、漸化関係によって定義されます。
SCSSの
F(n) = F(n-1) + F(n-2)
初期条件は F(0) = 0、F(1) = 1 です。 これは、フィボナッチ数列の-番目の数を取得するn
ために、()番目の数と(n-1
n-2
)番目の数を追加することを意味します。この再帰的な性質こそが、フィボナッチ数列が再帰を理解するのに完璧に適している理由です。 再帰とそれがフィボナッチ数列にどのように適用されるかについて理解が深まったところで、フィボナッチ数列を計算するための再帰ビューを実装する SmartPy コードに飛び込んでみましょう。
与えられた SmartPy コードは、 FibonacciView
再帰ビューを使用してフィボナッチ数列を計算するコントラクト を定義します。 これは、再帰関数が SmartPy でどのように作成され、使用されるかを理解するための優れた例です。
ニシキヘビ
SmartPy を SP としてインポートする
@sp.モジュール
デフmain():
class FibonacciView(sp.契約):
"""フィボナッチ数の合計を計算するための再帰ビューとの契約。 @sp.onchain_view()を呼び出します。
defフィボナッチ(self、n):
"""nまでのフィボナッチ数の和を返します。 引数:
n(sp.int):合計するフィボナッチ数。 帰る:
(sp.int):フィボナッチ数の和
"""
sp.cast(n, int)
n < 2 の場合:
nを返す
然も無くば:
n1 = sp.view("フィボナッチ", 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="フィボナッチビューの基本シナリオ", is_default=True)
def basic_scenario():
sc = sp.test_scenario(メイン) sc.h1("基本シナリオ") sc.h2("オリジネーション") C1 = メイン。フィボナッチビュー()
sc + = c1の
sc.verify(c1.フィボナッチ(8) == 21)
この FibonacciView
コントラクトには、 fibonacci
n 番目のフィボナッチ数を返す再帰ビュー関数があります。
この関数は で修飾 @sp.onchain_view()
されており、これがコントラクトのストレージに対する読み取り専用操作であることを示します。 この関数は、取得するフィボナッチ数列内の位置を表す整数 n
を引数として取ります。
関数内では、安全のために最初に整数にキャスト n
します。 関数の再帰的な部分が次に来ます。 が 2 より小さい場合 n
、フィボナッチ数列の最初の 2 つの数値は 0 と 1 であるため、単純に戻ります n
。 が 2 以上の場合n
、と n-2
のn-1
関数を再帰的に呼び出しfibonacci
、結果を加算することにより、n 番目のフィボナッチ数を計算します。これは、フィボナッチ数列を定義する漸化関係に相当します。 呼び出しは sp.view
、 fibonacci
関数自体に対するこれらの再帰的な呼び出しを作成します。
効率化のためのループの使用
再帰は理解するための貴重な概念ですが、特に大きな数を扱う場合は、効率が悪く、より多くの計算リソースが必要になる可能性があることに注意することが重要です。 スタックオーバーフローなどの問題を回避するには、ループを使用してフィボナッチ数列を計算し、計算されたフィボナッチ数を別の契約に格納する方が効率的なアプローチです。以下は、ループを使用するようにFibonacciView契約を変更する方法の高レベルの例です。
この修正された契約であるFibonacciCalculatorは、ループを使用してフィボナッチ数を効率的に計算し、契約のストレージに保存します。 次に、calculate_fibonacciエントリポイントを呼び出して、n番目のフィボナッチ数を取得できます。このアプローチはリソース効率が高く、n の大きな値に適しています。
ニシキヘビ
@sp.moduledef main()を使用します。
class FibonacciCalculator(sp.契約):
"""フィボナッチ数列を効率的に計算する契約。"""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 は負でない必要があります")
ストレージ = self.data
範囲(2、n + 1)のiの場合:
next_fib = storage[i - 1] + storage[i - 2]
ストレージ= storage.set(i、 next_fib)
sp.result(ストレージ[n])
テストのセクションに進みましょう。
テスト関数 basic_scenario
では、コントラクトの新しい FibonacciView
インスタンスを作成し、それをシナリオに追加してから、8 sc.verify
番目のフィボナッチ数がフィボナッチ数列に当てはまる21であることを確認します。
コードを実行するには、次のようにします。
SmartPy IDE を開きます。
提供されたコードをコピーしてエディターに貼り付けます。
「実行」ボタンをクリックします。 IDEの右側にテストシナリオが実行されているのが見えるはずです。 実行中の操作と検証中のチェックが表示されます。
このレッスンでは、多くの分野をカバーしています。 再帰の基本とプログラミングでの使用方法から、SmartPy の再帰ビュー、さらにはこれらの概念をフィボナッチ数列に適用する方法まで説明しました。 また、SmartPy で実際に動作するコード例も確認し、SmartPy IDE でこのコードを実行して検証する方法も学習しました。