通过VBA编码写入1到100之间的质数

时间:2018-07-01 04:22:06

标签: vba excel-vba primes excel

我找到了下面的编码,但是没有用。请分享更适合在VBA中写质数的代码

function createTable(){
  var table = document.getElementById("table");
  //Loop for rows
  for (var i = 1; i < 10; i++) {
    //Loop for columns
    for (var j = 1; j < 10; j++) {
      var cell = document.createElement("TR");
      //var i would be the row and var j would be the column
      cell.name=i+"-"+j;
      table.appendChild(cell);
    }
  }
}

3 个答案:

答案 0 :(得分:2)

这是该代码的稍微更有效的版本。修改了两件事:

a)由于1为not considered prime,所以外循环从2开始。

b)默认情况下,该数字被视为素数。如果检测到它不是素数,则停止进一步检查。 (在已发布的代码中,每次支票检测到数字为非质数时,都将设置值p =1。每次设置p = 1时,递增计数器将表明设置了1059次。)

Option Explicit
Sub generatePrimes()
    Dim flag As Boolean
    Dim n, i As Integer
    For n = 2 To 100
       flag = True
        For i = 2 To n - 1
          If n Mod i = 0 Then
             flag = False
             Exit For
          End If
        Next
        If flag = True Then
          Debug.Print i
        End If
    Next
End Sub

输出:

 2 
 3 
 5 
 7 
 11 
 13 
 17 
 19 
 23 
 29 
 31 
 37 
 41 
 43 
 47 
 53 
 59 
 61 
 67 
 71 
 73 
 79 
 83 
 89 
 97 

答案 1 :(得分:1)

我猜你是在用另一种语言翻译吗?您确实应该指出哪些行失败了,并且研究了什么。

例如,在VBA中进行简单的打印搜索将告诉您Print是无效的,但是Debug.Print可用于“控制台” 写入,即写入立即窗口(使用 Ctrl + G 打开)。

“”:我现在不记得正确的术语。这是在应用程序之间进行复制时的典型情况,因此请小心。在Visual Basic编辑器中使用的语音标记必须为""才能编译。

如果将Option Explicit放在代码的顶部,那么它会为您提供许多有关变量声明和拼写的漂亮警告。

您只需将100设为Integer就可以了,但是在这种情况下,IntegerLong没有优势,因此使用Long更为安全您决定将来超过Integer的容量,然后就有溢出的风险。您还需要在足够高的上限下排除mod

  

如果除数(第二个参数,则MOD function返回错误   在MOD函数中)乘以134,217,728,小于或等于   到要评估的数字(MOD中的第一个参数   功能)。

Microsoft建议重新使用=number-(INT(number/divisor)*divisor);我猜您可以将INT替换为CLng以与Longs保持一致。

Option Explicit
Private Sub cmdPrime_Click()
    Dim p As Long, n As Long, i As Long, iCounter As Long
    p = 1
    With ActiveSheet
        .Cells(iCounter + 1, 1) = "Prime Numbers are: " 'Debug.Print "Prime Numbers are: "
        For n = 2 To 100 ''< As pointed out 1 is not technically a prime btw so can start at 2
            For i = 2 To n - 1
                If n Mod i = 0 Then              ' If n - (CLng(n / i) * i) = 0 Then
                    p = 0
                    Exit For
                Else
                    p = 1
                End If
            Next
            If p = 1 Then
                iCounter = iCounter + 1
                .Cells(iCounter, 1) = n  'Debug.Print n  
            End If
        Next
    End With
End Sub

为将来的读者保留:来自@ChrisNeilsen的其他有用评论。

要测试n是否为质数,只需要测试可分解性,最高可达n的平方根。而且您只需要测试先前检测到的素数的可除性即可。而且,您甚至可以跳过n的值。

答案 2 :(得分:0)

在提高我的VBA技能的同时请问这个问题。这是我使用Sieve of Eratosthenes算法和6k ± 1优化并忽略5的所有偶数和除数的解决方案。

我创建了2个模块来分离逻辑功能和实用程序功能。打印约100,000中第一个10 seconds质数

模块1(PrimeNumber):

Option Explicit

Sub PrintPrimes()

Dim count As Long
Dim s As Object
Dim primes As New ArrayList
Dim startTime As Date
Dim endTime As Date

startTime = Now

Set s = Sheet1.Cells
count = s(1, 2) - 1

Set primes = GetPrimeList(count)

PrintArray primes, "Sheet1", 2
endTime = Now

s(1, 3) = "Elapsed time: " & ElapsedTime(endTime, startTime)

End Sub

Function GetPrimeList(count) As ArrayList

Dim primeList As New ArrayList
Dim i As Long
Dim currentInt As Long

i = 2
primeList.Add (2)
currentInt = 3

Do While (primeList.count <= count)
    If IsPrime(currentInt) Then primeList.Add (currentInt)
    currentInt = currentInt + 2 'ignore even numbers
Loop

Set GetPrimeList = primeList

End Function

Function IsPrime(number)

Dim i As Long
Dim maxValidator As Long
Dim possiblePrime As Boolean

i = 3
IsPrime = True
possiblePrime = False
maxValidator = Round_Up(Sqr(number))

If number = 3 Then
    IsPrime = True
    Exit Function
ElseIf number Mod 5 = 0 And number > 5 Then
    IsPrime = False
    Exit Function
End If

If (number Mod 6 = 1 Or number Mod 6 = 5) Then possiblePrime = True

If possiblePrime Then
    Do While (i <= maxValidator)
        If number Mod i = 0 Then
            IsPrime = False
            Exit Do
        End If
        i = i + 2 'ignore even divisors
    Loop
Else
    IsPrime = False
End If

End Function

模块2(实用程序):

Option Explicit

Function Round_Up(ByVal d As Double) As Long
    Dim result As Long
    result = Math.Round(d)
    If result >= d Then
        Round_Up = result
    Else
        Round_Up = result + 1
    End If
End Function

Function PrintArray(Data, SheetName As String, intStartRow As Integer)

    Dim oWorksheet As Worksheet
    Dim item As Variant
    Dim i As Long
    Set oWorksheet = ActiveWorkbook.Worksheets(SheetName)

    i = intStartRow
    For Each item In Data
        oWorksheet.Cells(i, 1) = item
        i = i + 1
    Next

End Function

Function ElapsedTime(endTime As Date, startTime As Date)
    Dim strOutput As String
    Dim Interval As Date

    ' Calculate the time interval.
    Interval = endTime - startTime

    ' Format and print the time interval in days, hours, minutes and seconds.
    strOutput = Int(CSng(Interval)) & " days " & Format(Interval, "hh") _
        & " Hours " & Format(Interval, "nn") & " Minutes " & _
        Format(Interval, "ss") & " Seconds"
    ElapsedTime = strOutput

End Function

输入要在单元格B1中列出的素数。

Alt+F8,然后选择PrintPrimes(默认情况下应选择),然后单击Run

Voila!素数列表将从单元格A2中打印出来。 单元格A1保留为空白,以供用户输入输入要打印的素数

注意: 我使用Long数据类型代替Integer来覆盖更多值。如果要打印的值比2,147,483,647多,则只需将Long模块中的Double替换为PrimeNumber。如果使用Double数据类型,您会发现性能显着下降!

PS:请确保使用this链接尽早绑定 mscorlib.dll