• ベストアンサー

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

こんにちは 再帰処理を用いて階乗を求めるプログラムについて の質問です。 以下のように考えたのですが、 まったく駄目なようです。 どこをどのように直したらいいのか いまいちわかりません。 どなたか教えて下さい。お願いします。 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

  • 1724
  • お礼率57% (39/68)

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

  • ベストアンサー
  • i536
  • ベストアンサー率32% (75/231)
回答No.2

再帰処理の場合、蛇が自分の尻尾を呑んでいるようなプログラムになります。 ご質問はループ処理であって、再帰になっていないと思います。 下記に再帰関数KEISANのサンプルを示します。 一応実行して確認しました。 Private Sub CommandButton1_Click() Dim n As Integer n = Val(TextBox1)   TextBox2 = KEISAN(n) End Function Private Function KEISAN(n) If n <= 1 Then KEISAN = 1 Else KEISAN = n * KEISAN(n - 1) End If End Function

1724
質問者

お礼

お礼が遅れ申し訳ありませんでした。 ご回答ありがとうございました。 お陰様で何がわからなかったのか 理解することができました。

その他の回答 (6)

  • ARC
  • ベストアンサー率46% (643/1383)
回答No.7

KEISAN = n * KEISAN(n - 1) ↑が再帰してる部分かと思います(^^;

回答No.6

>拝見したところ、自分自身を呼び出しているし、十分再帰処理かと思うのですが… KEISAN()が再帰対象の関数だと思いますが、 この関数の中でKEISAN()を呼び出しているようには見えませんけど・・・ >ちなみに、ByRefでも問題なく再帰できますよ。 そうですね。目的によるでしょう。 ちょっと言葉足らずでしたね。 今回のケースはByValの方が効率的かと思います。

  • ARC
  • ベストアンサー率46% (643/1383)
回答No.5

>自分自身を呼び出していませんから、再帰とは言えないのではないでしょうか。 ん? 拝見したところ、自分自身を呼び出しているし、十分再帰処理かと思うのですが… ちなみに、ByRefでも問題なく再帰できますよ。 例えば、サブフォルダに含まれるファイルの一覧を再帰検索を行うとすると、フォルダを一階層降りるごとに大量のテキストデータが発生します。これを一々ByValで渡したりしてたら埒が明きません。 こんな時は文字列の配列を作って、引数の中で参照渡しした方がはるかに効率がいいんですよね。

1724
質問者

お礼

ご回答ありがとうございました。

回答No.4

再帰処理とは自分自身を呼び出すことです。 この場合KEISANが演算処理だと思いますが、 自分自身を呼び出していませんから、再帰とは言えないのではないでしょうか。 演習として再帰に取り組んでおられるのでなければ、 VB上での階乗の標記は x^n (ex. 2の3乗は 2^3) で表現できますが。 再帰とするなら、 パラメータにByVal(値渡し)を付け、計算結果を関数の戻り値としょう。 ByValを省略すると、ByRef(参照渡し)となってしまいます。

1724
質問者

お礼

値渡しと参照渡しは勉強不足でした。 ためになります。ありがとうございました。

noname#5584
noname#5584
回答No.3

Private Sub CommandButton1_Click() Dim n As Long Dim f As Long n = CLng(TextBox1.Text) TextBox2.Text = CStr(Recur(n)) End Sub Public Function Recur(ByVal arg As Long) As Long If arg = 1 Then Recur = arg Exit Function End If Recur = arg * Recur(arg - 1) End Function ↑こんな感じでできるようです。 でも、階乗計算を再帰で実現する必要性が理解できません。(笑) (For ループでこと足りるので) # VBで再帰ができないのは初めて知りました。勉強になりました。 # 私の環境では上記で問題なく動くのですが、何か見落としているのでしょうか・・・?

1724
質問者

お礼

お礼が遅れ申し訳ありませんでした。 アドバイスありがとうございました。 今回は再帰処理の勉強であったため、 再帰処理で階乗計算を行うプログラムの作成でした。

  • ymmasayan
  • ベストアンサー率30% (2593/8599)
回答No.1

残念ですがVBでは再帰処理は出来ないはずですが。 再帰処理ができる条件は同じ関数の中で1つの変数の世代管理ができることです。 VBにはこの機能がありません。 再帰処理を使わずに単に階乗を計算することなら出来ますが。

1724
質問者

お礼

お礼が遅れ申し訳ありませんでした。 ご回答ありがとうございました。 今回は再帰処理の勉強であったため、 あえて再帰処理を用いたプログラムでした。

関連するQ&A

  • VB.NETで階乗を求めるプログラムを作成する

    再帰を使わず、For文による繰り返しにより、階乗を求めるプログラムを作成したいのです。 ↓ここからどうすれば良いか、ご教授お願い致します。 Dim n , i As Integer n = Textbox1.Text For i = 1 To n n = n * ( n - 1 ) Next Textbox2.Text = n

  • 階乗のマクロ

    階乗のマクロを作りたいのですが、全然できません。どこを変えたらいいのか教えて下さい。ちなみに今こうなっています。 ------------------------------------------------ Sub exam5() Dim intA As Integer Dim intB As Integer Dim intC As Integer intA = Application.InputBox("数値を入力してください。") intB = (intA - 1) intC = (intA) * (intB) MsgBox (intC) End Sub Function kaijou(intA As Integer, intB As Integer) As Integer kaijou = intA * intB End Function ------------------------------------------------ どうかお願いします。

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

    最近プログラミングを勉強し始めた者です。 教科書と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…」と始められるかが分かりません。 まだこの単元を消化しきっていないため、質問内容もままならない点がありますが、ご理解できましたら是非回答をよろしくお願いします。

  • 0から12までの値nを入力し、nと階乗n!の値を表示しなさいという問題

    0から12までの値nを入力し、nと階乗n!の値を表示しなさいという問題ですが、一つの数字しか計算が出来ません 5と12の場合は String "5 12" から型 'Long' への変換は無効です。と出てきてしまいます。 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim n As Long Dim f As Long n = CLng(TextBox1.Text) ←ここにエラーが出ます。 TextBox2.Text = CStr(Recur(n)) End Sub Public Function Recur(ByVal arg As Long) As Long If arg = 1 Then Recur = arg Exit Function End If Recur = arg * Recur(arg - 1) End Function End Class というプログラムです。分かる方よろしくお願いします。 実行エラーです。

  • 1から入力された数までの素因数を数えるプログラム

    こんにちは 1から入力された数(N)までの素因数を数えるプログラムを 作成したいのですが、うまくいきません。 たとえば10と入力すると2と表示されてしまいます。 どこがおかしいのかわかりません。 どなたか教えてください。おねがいします。 N個の配列を用意し、1を入れていき、 素因数でない数の要素には0をいれて、 最終的に1が入っている配列の数を数えて1~Nまでの 素因数の数を数える方法を考えています。 Dim M As Integer Dim N As Integer Dim i As Integer Dim j As Integer Dim sum As Integer Dim L(1000) As Double N = Val(TextBox1) M = N i = 1 Do Until i > N L(i) = 1 i = i + 1 Loop i = 2 Do Until i > M j = i * 2 Do Until j > M L(j) = 0 j = j + 1 Loop i = i + 1 Loop sum = 0 For i = 2 To N If L(i) = 1 Then sum = sum + 1 End If Next i

  • 0から12までの値nを入力し、nと階乗n!の値を表示しなさいという問題

    0から12までの値nを入力し、nと階乗n!の値を表示しなさいという問題です。 前にこのプログラムで複数個、同時には計算できない問題を自分で解決したのですがこんどは0が計算できないようです。 System.StackOverflowException' のハンドルされていない例外が WindowsApplication1.exe で発生しました。 とでます Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim n As Long Dim f As Long n = CLng(TextBox1.Text) TextBox2.Text = CStr(Recur(n)) End Sub Public Function Recur(ByVal arg As Long) As Long ←ここにエラーが If arg = 1 Then Recur = arg Exit Function End If Recur = arg * Recur(arg - 1) End Function End Class というプログラムです。分かる方よろしくお願いします。 実行エラーです。

  • VBのfunctionの引数について

    2の Double型と 3の Single型のように送る側と受け取る側の変数の型が 違ってもよいのでしょうか?プログラムはそのまま実行できたのですが・・・・。 Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim koku As Integer Dim san As Integer Dim rika As Integer Dim ave As Double------------------------------------1 koku = Val(TextBox1.Text) san = Val(TextBox2.Text) rika = Val(TextBox3.Text) ave = (koku + san + rika) / 3 Label5.Text = Round(ave)-------------------------------2 End Sub Private Function Round(ByVal sngvalue As Single-----3) As Integer Dim intvalue As Integer intvalue = Int(sngvalue + 0.5) Return intvalue End Function End Class

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

    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

  • 値渡しについて

    UserForm1で以下のように求めた値「R」を UserForm2に渡すにはどのようにすればよいのでしょうか。 **************************************** <UserForm1(コード)> Public R As Integer ----------------------------------- Private Sub CommandButton1_Click()    Dim N As Integer        :    N = TextBox1.Text    R= N * 2 + 3        : End Sub **************************************** <UserForm2(コード)> Private Sub CommandButton1_Click()   Dim i As Integer       :   For i = 4 To R       :   Next i       : End Sub **************************************** どなたか教えて下さい。

  • VB2005 図形

    VisualBasic2005で Dim n As Integer, m As Integer Dim i As Integer, j As Integer Const lenn = 1500, PAI = 3.14159 Dim th As Single, th1 As Single, th2 As Single Dim x1 As Integer, x2 As Integer Dim y1 As Integer, y2 As Integer n = Val(TextBox1.Text) m = Val(TextBox2.Text) If n < 2 Or m < 2 Then   Exit Sub End If For i = 0 To n - 1   For j = 1 To n - 1     th = j * (PAI / n)     th1 = i * (PAI / m) + th     th2 = i * (PAI / n) - th     x1 = Math.Cos(th1) * lenn + 2000     y1 = Math.Sin(th1) * lenn + 2000      x2 = Math.Cos(th2) * lenn + 2000      y2 = Math.Sin(th2) * lenn + 2000   Next Next の様なコードを使って 球をPictureBoxに書きたいのですが どこにどんなコードが足りないのでしょうか? 教えて下さい

専門家に質問してみよう