查找数字是Prime还是使用excel公式显示素因子?

时间:2017-03-28 23:36:02

标签: excel excel-vba excel-formula vba

我在Col A和col B中有整数,如果它没有数字本身的其他因素,我想显示结果'Prime'。如果例如37的结果是'Prime',那么这就是这样的,如果它的44那么结果将是2x2x11。我怎么能用excel公式做到这一点?截屏:

enter image description here

3 个答案:

答案 0 :(得分:4)

免责声明:以下代码来自此very useful VB.NET example

Option Explicit

Sub Test()
    Debug.Print FindFactors(2)
    Debug.Print FindFactors(3)
    Debug.Print FindFactors(11)
    Debug.Print FindFactors(12)
    Debug.Print FindFactors(13)
    Debug.Print FindFactors(16)
    Debug.Print FindFactors(17)
    Debug.Print FindFactors(24)
    Debug.Print FindFactors(25)
    Debug.Print FindFactors(11234)
    Debug.Print FindFactors(67894)
End Sub

Function FindFactors(lngNumber As Long) As String
    Dim collFactors As Collection
    Dim lngFactor As Long
    Dim lngCounter As Long
    Dim strFactors As String
    Dim strFactor As String

    Set collFactors = New Collection

    ' Take out the 2s.
    Do While (lngNumber Mod 2 = 0)
        collFactors.Add 2
        lngNumber = lngNumber / 2
    Loop

    ' Take out other primes.
    lngFactor = 3
    Do While (lngFactor * lngFactor <= lngNumber)
        If (lngNumber Mod lngFactor = 0) Then
            ' This is a factor.
            collFactors.Add lngFactor
            lngNumber = lngNumber / lngFactor
        Else
            ' Go to the next odd number.
            lngFactor = lngFactor + 2
        End If
    Loop

    ' If num is not 1, then whatever is left is prime.
    If lngNumber > 1 Then
        collFactors.Add lngNumber
    End If

    ' make a string out of collection
    strFactors = ""
    If collFactors.Count = 1 Then
        strFactors = "Prime"
    Else
        For lngCounter = 1 To collFactors.Count
            strFactors = strFactors & collFactors(lngCounter)
            If lngCounter < collFactors.Count Then
                strFactors = strFactors & "x"
            End If
        Next lngCounter

    End If

    FindFactors = strFactors

End Function

输出:

Prime
Prime
Prime
2x2x3
Prime
2x2x2x2
Prime
2x2x2x3
5x5
2x41x137
2x83x409

可以在工作表中使用:

enter image description here

答案 1 :(得分:2)

这是一个有点简单的递归版本。它基于这样的想法:一旦你确定了一个因子,你将数字除以该因子,然后将注意力转移到其余的因素上。

Function Factor(ByVal n As Long, Optional FirstTrial As Long = 2) As String
    Dim i As Long
    Dim t As Long
    Dim limit As Long
    Dim rest As String
    Dim s As String

    If n = 1 Then
        Factor = n
        Exit Function
    End If
    limit = Int(Sqr(n))
    t = FirstTrial
    Do While t <= limit
        If n Mod t = 0 Then
            rest = Factor(n / t, t)
            If rest <> "1" Then
                s = t & "x" & rest
            End If
            Factor = s
            Exit Function
        Else
            If t = 2 Then t = 3 Else t = t + 2
        End If
    Loop
    'if we get here:
    Factor = n
End Function

Function PrimeOrFactor(n As Long) As String
    Dim s As String
    s = Factor(n)
    If n = 1 Then
        PrimeOrFactor = "Neither"
    ElseIf (s) = Trim(n) Then
        PrimeOrFactor = "Prime"
    Else
        PrimeOrFactor = s
    End If
End Function

测试如下:

Sub test()
    Dim i As Long
    For i = 1 To 20
        Cells(i, 1) = i
        Cells(i, 2) = PrimeOrFactor(i)
    Next i
End Sub

输出:

enter image description here

答案 2 :(得分:0)

使用下面包含的Mod with Doubles对上面的John Coleman的出色代码进行少许修改,将允许分解整数,直到Excel的15位数字限制。具有较大因素的数字可能会明显慢一些。例如,在Core i3上大约5秒钟内,562,951,983,465,953正确地分解为16,777,259 x 33,554,467。

Function Factor(ByVal n As Double, Optional FirstTrial As Double = 2) As String 'Changed
    Dim i As Long
    Dim t As Double 'Changed
    Dim limit As Long
    Dim rest As String
    Dim s As String

    If n = 1 Then
        Factor = n
        Exit Function
    End If
    limit = Int(Sqr(n))
    t = FirstTrial
    Do While t <= limit
        If FMod(t, n) = 0 Then 'Changed
    .
    .
    .

    Public Function FMod(a As Double, b As Double) As Double
        FMod = a - Fix(a / b) * b

        'http://en.wikipedia.org/wiki/Machine_epsilon
        'Unfortunately, this function can only be accurate when `a / b` is outside [-2.22E-16,+2.22E-16]
        'Without this correction, FMod(.66, .06) = 5.55111512312578E-17 when it should be 0
        If FMod >= -2 ^ -52 And FMod <= 2 ^ -52 Then '+/- 2.22E-16
            FMod = 0
        End If
    End Function