[[20220106171527]] 『素数判定プログラミング』(初心者です。) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『素数判定プログラミング』(初心者です。)

1.与えられた整数値 x が素数か否かを判定する Function プロシージャ primF を作成する。この Function プロシージャはユーザとは対話せず、引数で x を受け取り、戻り値として True または False を返すようにしたいです。その時、InputBox や MsgBox のようなユーザと対話するためのダイアログボックスは表示しないようにしたいです。

2.与えられた整数値 x を素因数分解する Function プロシージャ factorizeF を作りたいです。1と同様、引数と戻り値だけでデータを処理するようにしたいです。

3.Excel ワークシート上から primF と factorizeF を呼び出し、十分に動作を確認できるようにしたいです。

4.factorizeF の戻り値となる文字列表現を整理し、 [ ] で囲んだ数値リストが返されるように整えて、最初だけカンマ(,)が s に入り込むのを抑制し、一番最後に開き括弧([)と閉じ括弧(])で囲えるようにしたいです。

下二個のプログラミングが分かりませんでした。質問が多くて、申し訳ないのですが、教えていただけると助かります。

'素数を判定するSubプロシージャ
Sub primS()
Const title As String = "素数判定"
Dim x As Integer
Dim k As Integer

    x = InputBox("整数値(2〜32767)", title)

    For k = 2 To x
        If x Mod k = 0 Then Exit For
    Next k

    If k < x Then
        MsgBox x & "は素数ではありません。(" & k & "で割れました。)", , title
    Else
        MsgBox x & "は素数です。", , title
    End If
End Sub

'素因数分解をするSubプロシージャ
Sub factorizeS()
Dim x As Integer, y As Integer
Dim k As Integer
Dim s As String

    x = InputBox("整数値(2〜32767)", "素因数分解")
    y = x
    k = 2
    Do
        If y Mod k = 0 Then
            s = s & ", " & k
            y = y \ k
        Else
            k = k + 1
        End If
    Loop Until y = 1

    MsgBox x & " ⇒ " & s, , "素因数分解"
End Sub

'素数を判定するFunctionプロシージャ
Function primF(x As Integer) As Boolean

    primF = True
End Function

'素因数分解をするFunctionプロシージャ
Function factorizeF(x As Integer) As String

    factorizeF = ",1,2,3,4,5"
End Function

< 使用 Excel:unknown、使用 OS:unknown >


これはカンニングOKな課題ですか。
出題者もきっと見ていますよ。
(婆) 2022/01/06(木) 18:36

Functionプロシージャに関する復習問題ですね。
ご自分でトライしたほうがよいと思いますよ。

基本的なロジックはサブプロシージャで与えられているわけですから、
その内容を理解して、Functionプロシージャに変換するという問題ですね。
途中までで結構ですから頑張ってみた結果を示してみてください。

# n が素数であるかの判定は、普通は ルートn までの整数を使って
 判定すれば足りるわけですが、
# そうした考慮はないですし、学習問題ということなんでしょう。
(γ) 2022/01/06(木) 22:36


Function primF(x As Integer)
If x = 2 Or x = 3 Then
primF = True
Exit Function
End If

If x Mod 2 = 0 Then
primF = False
Exit Function
End If

r = Int(Sqr(x))
For k = 3 To r Step 2
If x Mod k = 0 Then
primF = False
Exit Function
End If
Next k

primF = True
End Function

Function factorizeF(x As Integer)
r = Int(Sqr(x))
factorizeF = "["Do While x Mod 2 = 0
factorizeF = factorizeF &"2,"x = x / 2
Loop

For k = 3 To r Step 2
Do While x Mod k = 0
factorizeF = factorizeF &k &","x = x / k
Loop
Next k
If x >= k Then
factorizeF = factorizeF & x & "]"
Else
factorizeF = Left(factorizeF, Len(factorizeF) - 1) & "]"
End If
End Function

どうしてもfactorizeF = のところができません
(初心者です。) 2022/01/07(金) 00:32


 サブプロシージャをそのまま活用したほうがよいと思います。課題なんでしょうから。
 サブプロシージャで作成した文字列 s を加工するだけでよいと思います。

 Function factorizeF(x As Long) As String
     Dim s As String
     Dim y As Long
     Dim k As Long

     y = x
     k = 2
     Do
         If y Mod k = 0 Then
             s = s & ", " & k
             y = y \ k
         Else
             k = k + 1
         End If
     Loop Until y = 1

     factorizeF = "[" & Mid(s, 2) & "]"  ' 修正はここだけです。
 End Function
(γ) 2022/01/07(金) 01:11

 Function primF(x As Long) As Boolean
    Dim k As Long
    If x > 1 Then
        For k = x ^ 0.5 To 2 Step -1
            If x Mod k = 0 Then
                Exit Function
            End If
        Next
        primF = True
    End If
 End Function

 Function FactorizeF(x As Long) As String
    FactorizeF = "[" & Factoring(x) & "]"
 End Function

 Function Factoring(x As Long) As String
    Dim buf As String
    Dim k As Long
    If x > 1 Then
        For k = x ^ 0.5 To 2 Step -1
            If x Mod k = 0 Then
                buf = MargeF(Factoring(k), Factoring(x \ k))
                Exit For
            End If
        Next
        If buf = "" Then
            buf = x
        End If
        Factoring = buf
    End If
 End Function

 Function MargeF(x As String, y As String) As String
    Const D As String = ","
    Dim xVar, yVar
    Dim i As Long, ix As Long, iy As Long
    xVar = Split(x, D)
    yVar = Split(y, D)
    ReDim Var(UBound(xVar) + UBound(yVar) + 1)
    For i = 0 To UBound(Var)
        Select Case True
            Case iy > UBound(yVar)
                Var(i) = xVar(ix)
                ix = ix + 1
            Case ix > UBound(xVar)
                Var(i) = yVar(iy)
                iy = iy + 1
            Case CLng(xVar(ix)) < CLng(yVar(iy))
                Var(i) = xVar(ix)
                ix = ix + 1
            Case Else
                Var(i) = yVar(iy)
                iy = iy + 1
        End Select
    Next
    MargeF = Join(Var, D)
 End Function

雑ですが別案
あまり課題の解答向きの内容ではありません
(きまぐれおじさん) 2022/01/07(金) 04:13


https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11252182351
他サイトに同じ課題についての質問がありました。
(きまぐれおじさん) 2022/01/07(金) 04:26

  こんなことかな?
  xが2以上の判定を入れないとマズい気がします。

 '素数を判定するSubプロシージャ
 Function primS(x As Integer) As Boolean
     Dim k As Integer

     If x < 2 Then
         primS = Null
         Exit Function
     Else
         For k = 2 To x
             If x Mod k = 0 Then Exit For
         Next k

         primS = k >= x
     End If
 End Function

 '素因数分解をするSubプロシージャ
 Function factorizeS(x As Integer)
     Dim y As Integer
     Dim k As Integer
     Dim s As String

     If x < 2 Then
         factorizeS = Null
         Exit Function
     Else
         y = x
         k = 2

         Do
             If y Mod k = 0 Then
                 s = s & ", " & k
                 y = y \ k
             Else
                 k = k + 1
             End If
         Loop Until y = 1

         factorizeS = x & " ⇒ " & Right(s, Len(s) - 2)
     End If
 End Function

 '素数を判定するFunctionプロシージャ
 Function primF(x As Integer) As Boolean
     primF = primS(x)
 End Function

 '素因数分解をするFunctionプロシージャ
 Function factorizeF(x As Integer) As String
     factorizeF = factorizeS(x)
 End Function

(半平太) 2022/01/07(金) 06:43


 質問の課題から離れて、
 素因数分解をワークシート上で多数実行するとした場合(*)の方法を考えてみました。
 対象範囲内の素数を予め算定しておき、それをdictionaryに持つという案です。

 ・素数列挙   が、素数を調べて辞書に持つ部分
 ・素数判定   これは、辞書にあれば素数と判定します
 ・素因数分解 整数の素因数分解をカンマ区切りで返す、ユーザー定義関数です。
              ワークシートに置けます。

 ご参考まで。
 (*)と言われても、こんなこと実生活ではありえないですけどね。ま、遊びということで。)

 Option Explicit
 Dim dic As Object

 '素数テーブルがあるかチェックし、なければ作成
 Sub checkPrimeTable()
     If dic Is Nothing Then
         Set dic = CreateObject("Scripting.Dictionary")
         Call 素数列挙
     End If
 End Sub

 ' 1から32767までの素数をdictionaryに持つ
 Sub 素数列挙()
     Const c As Long = 32767
     Dim c2 As Long
     Dim j&, k&
     c2 = Int(c ^ 0.5)

     ReDim mat(1 To c)
     For k = 2 To c2
         j = k
         Do Until j > c - k
             j = j + k
             mat(j) = 1
         Loop
     Next
     For k = 2 To c
         If mat(k) = 0 Then dic(k) = Empty
     Next
 End Sub

 '素数ならtrueを返す
 Function 素数判定(ByVal n As Long)
     Call checkPrimeTable
     素数判定 = dic.Exists(n)
 End Function

 Function 素因数分解(ByVal n As Long) As String
     Dim n2 As Long
     Dim aryL As Object
     Dim prime As Variant

     Call checkPrimeTable

     If 素数判定(n) Then
         素因数分解 = CStr(n)
         Exit Function
     End If

     Set aryL = CreateObject("System.Collections.ArrayList")
     n2 = Int(n ^ 0.5)
     For Each prime In dic.Keys
         If prime > n2 Then Exit For
         Do Until n Mod prime <> 0
             aryL.Add prime
             n = n / prime
             If 素数判定(n) Then
                 aryL.Add n
                 Exit For
             End If
             If n = 1 Then Exit For
         Loop
     Next
     素因数分解 = Join(aryL.ToArray, ",")
 End Function

(γ) 2022/01/07(金) 14:30


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.