• ベストアンサー

再帰構造のアルゴリズムで困っています。

最近プログラミングを勉強し始めた者です。 教科書とWebを使って勉強しているのですが、なかなか厳しいです。 初歩的な質問であると思いますがお許しください。 フィボナッチ数列の8番目の数字を再帰構造を用いて表示させるプログラムを作りました。 Sub saikikouzou() n = 8 Cells(1, 1) = keisan(n) End Sub Function keisan(n) If n < 3 Then keisan = 1 Else keisan = keisan(n - 1) + keisan(n - 2) End If End Function 一般的にフィボナッチ数列と言われると「1.1.2.3.5.8.13.21」という数列であると理解しています。上記のプログラムもそのつもりで作成しました。 しかし今は「1.2.3.5.8.13.21.34」という数列の8番目を再帰構造を使って求めたいと考えています。 つまり、最初の数字を「1,1…」と始まるのではなく「1.2…」と始めたいのです。 私のプログラムだと、 If n < 3 Then keisan = 1 の部分で最初の数字が「1.1」と決めているため、良くないことは理解できましたが、どうすれば「1.2…」と始められるかが分かりません。 まだこの単元を消化しきっていないため、質問内容もままならない点がありますが、ご理解できましたら是非回答をよろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

keisan(n)に、初項、第2項を追加して渡す、というのはいかがでしょう? #蛇足ながら、この場合、再帰構造を使用しないほうがよいのですが。 #計算量がnの2乗のオーダーで増えますから。 #(計算回数はフィボナッチ数列そのもの?) Sub saikikouzou() n = 8 'a1=Cells(2, 1) 'a2=Cells(2, 2) a1=1 a2=2 Cells(1, 1) = keisan(n,a1,a2) End Sub Function keisan(n,a1,a2) If n = 1 Then keisan = a1 Else If n = 2 Then keisan = a2 Else keisan = keisan(n - 1) + keisan(n - 2) End If End If End Function

toiarush
質問者

お礼

ご回答どうもありがとうございます。 Function keisan(n,a1,a2) という発想は無かったのでとても参考になりました。 只今、実行してみましたところ、コンパイルエラーで「引数が省略されている」と出てしまいましたが、何とか自分でもこのエラーは解消できるように努力してみます。 このことに関して、引き続きご教授の方も受け付けております。 とても参考になりました。 ありがとうございました。

その他の回答 (2)

回答No.3

しまった。内部でも関数を呼び出していたのでした。 >コンパイルエラーで「引数が省略されている」 引数は普通、省略不可能ですので、言い換えれば「必要な個数の引数が指定されていません」ということでして。 >keisan = keisan(n - 1) + keisan(n - 2) 正しくは以下のとおりです。(きっと・・(汗)) keisan = keisan(n - 1,a1,a2) + keisan(n - 2,a1,a2)

toiarush
質問者

お礼

ありがとうございました。 なるほど、エラーはそういうことを言っていたんですね! 日々勉強です。 とても参考になりました。 お世話になりました。

noname#77845
noname#77845
回答No.1

If n < 3 Then  ↓ If n < 2 Then 1番目からじゃなく、0番目から始めれば8番目は34になります。

toiarush
質問者

補足

ご回答ありがとうございます。 恐れ入りますが、 If n < 3 Then keisan = 1 この部分で「もしも~~の場合、1と2を~~に入れる」のような記述は出来ないものでしょうか? と言うのも、実を申しますと将来的にシートの読み込みをさせたく、任意の2つの数字を入れるとフィボナッチ風(?)の数列を発生させるようにすると面白いかな、と勝手に考えています。 このようなことをするためには、まず上記の部分で「○○=1 ○○=2」のような書き方にするのが第一歩目かな、と考えたのですが考え方は的外れでしょうか?

関連するQ&A

  • 再帰処理を用いて階乗を求めるプログラム

    こんにちは 再帰処理を用いて階乗を求めるプログラムについて の質問です。 以下のように考えたのですが、 まったく駄目なようです。 どこをどのように直したらいいのか いまいちわかりません。 どなたか教えて下さい。お願いします。 Private Sub CommandButton1_Click() Dim n As Integer 階乗する数 Dim f As Integer 階乗する数の階乗した値 n = Val(TextBox1)   Do While f > 1 KEISAN n, f Loop TextBox2 = f End Function Function KEISAN(n, f) If n <= 1 Then f = 1 Else f = n * f(n - 1) End If End Function

  • 再帰アルゴリズム

    再帰アルゴリズムの練習のため問題に取り組んでいるのですが、問題集に解答がついておらずイマイチ理解できていないので教えていただけると助かります。 d個の毎インデックスで(0,0,...,0)から(n,n,...,n)まで反復させるアルゴリズムを反復アルゴリズムと再帰アルゴリズムの両方考えよ です。 (0,0,0,...,0) (1,0,0,...,0) (1,1,0,...,0) (1,1,.....,1) ... (n,n,.....,n) と表示を繰り返すプログラムでいいのかな、と思い反復の方は二十ループを用いてプログラムかけたんですが、再帰の法がアルゴリズムがどうも理解できていません。 ご教授願えればと思い、お願いします。

  • フィボナッチ数列のプログラム

    問題で フィボナッチ数列のn番目の値を計算する関数 int fib(int n) を再帰的に定義し、この関数を利用してフィボナッチ数列の最初の10個を表示するプログラムを書けという問題があるのですが、大まかな流れは想像できるのですが、できないので困っております。  何方か教えてください。

  • 組み合わせを抽出するために使う再帰呼び出しについて

    1,2,3,4,5の数列から3の数の組合せをワークシートに表示するプログラムを作っています。 このソースは以前他の質問に載っていたものを自分用に多少アレンジしたものです。構造は再帰呼び出しを使って、123、124、125、134、135、145、234、235…345という形で結果を出力します。いろいろと試してみて、計算結果は正しいとわかったのですが、デバックをしていて1つどうしても理解できないことがありました。計算結果が145から234になるとき、カーソルがSub combiPrのEnd subを指したあと直前のEnd ifに移ります。その後Forに移って234以降の計算を始めます。どうしてEnd Subからこのような動作をするのかわかる方いらっしゃいましたら是非ワケを教えてください。よろしくお願いしますm(_ _)m Const m As Integer = 3 '←取り出す個数 Const n As Integer = 5 '←サンプル数 Dim rStr As String Dim mRow As Integer Dim Nest As Integer Dim A(10) As Variant Sub combi() Cells.ClearContents mRow = 0 Nest = 0 combiPr (0) End Sub Sub combiPr(n1) Dim mCol As Integer For nn = n1 + 1 To n - m + Nest + 1 Nest = Nest + 1 A(Nest) = nn If Nest = m Then mRow = mRow + 1 For mCol = 1 To m Worksheets(1).Cells(mRow, mCol).Value = A(mCol) Next Else Call combiPr(nn) End If Nest = Nest - 1 Next nn End sub

  • 関数の再帰処理

    1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657... という数列(フィボナ数列)を再帰処理でだしたいのですが・・・・・ include <stdio.h> int function( int ); int main( void ){ int n; do { printf( "0 以上の整数値を入力して下さい→ " ); scanf( "%d", &n ); }while ( n < 0 ); printf( "計算結果: %d\n", function( n ) ); getchar(); getchar(); return 0; } int function( int n ){ //フィボナの処理(function)の再帰呼び出しによる } function内に再帰処理を用いてprintf( "計算結果: %d\n", function( n ) );で画面出力したいのですが・・・・・・。

  • 再帰について

    一般的(?)に、フォルダ内にあるファイルをサブフォルダまで含めて表示するとき、再帰という方法を用いると思います。 フォルダのようなツリー構造の場合に、再帰を使わなくても表示できるプログラムは作れるのでしょうか? (BASIC等は再帰が使えないと聞いたのですが・・・) 考え方だけで良いので、アドバイスお願いします。

  • マクロで組み合わせの数を求める計算(再帰的)

    Ms-excelで下記のマクロを作ると「=K(n,i)」と適当なセルに入れることで、組み合わせ計算(=高校の教科書の表記では nCi )を行えるようですがどういう原理で組み合わせ計算をしているのか理解できないため質問します。 ------------ Function K(n, i) K = 1 If i > 0 Then K = (n - i + 1) / i * C(n, i - 1) End If End Function ------------ 以下高校の教科書に沿ってK(n, i)を nCi と書きますが、 例えば5C5を求めるとき上のプログラムだと、 5C5 = 5C4*1/5 5C4 = 5C3*1/2 5C3 = 5C2*1 5C2 = 5C1*2 (以下i>0となるためストップ) とさかのぼって計算して(再帰的定義?)いるようですが、5C1(マクロでK(5, 1)の値 )が定義されていない以上はさかのぼっていっても値が決まらないように思いますがどういう原理で組み合わせ計算をしているのでしょう?またK=1と定義する意味はあるんでしょうか?

  • 流れ図・・・

    フィボナッチ数列の第n項を計算する関数fibo(n)の、再帰呼び出しを利用した流れ図はどのようになるんですか?どなたか教えてください。フィボナッチ数列は分かるんですが…

  • フィボナッチ数列とルーカス数列を使った証明

    フィボナッチ数列とルーカス数列(リュカ数列)使った証明です。 L(n)をルーカス数列のn番目の数字、F(n)をフィボナッチ数列のn番目の数字として、 L(0) = 2, L(1) = 1 F(0) = 0, F(1) = 1 の場合、 L(n) = F(n-1) + F(n+1) になることを証明しようと思ってます。 ビネの公式を使って証明しようと思ったんですが、うまく行きませんでした。それに、もっと簡単な方法があると思うんですが、どなたかわかりませんか?

  • 再帰に関する質問です。

    再帰に関する質問です。 class Test  def fact(n)    return 1 if n == 0    n * fact(n - 1)    p n  end end myfact = Test.new p myfact.fact(3) なぜ、"p n"をメソッドの中に入れると最後の "p myfact.fact(3)"の結果が3に なるのでしょうか。 "p n"をコメントアウトすると正常に6という結果がでます。 この再帰の構造は、 #1st loop fact(3)。 n = 3  3 * fact(2) end #2nd loop fact(2)  n = 2  2 * fact(1) end #3rd loop fact(1)  n = 1  1 * fact(0) end #last loop fact(0) return 1 end となってますよね。ここで最後のfact(0)から、リバースしていくわけで、 fact(1) 1 * 1 p n =>1 end fact(2) 2 * 1 p n => 2 end fact(3) 3 * 2 p n => 3 end ここまではわかります。ではなぜ最後の"p myfact.fact(3)"が3になるのでしょ うか。

    • ベストアンサー
    • Ruby

専門家に質問してみよう