通过VBA编码写入1到100之间的素数
我发现下面的代码,但它不工作。请分享在VBA中编写素数的更合适的代码通过VBA编码写入1到100之间的素数,vba,excel,primes,Vba,Excel,Primes,我发现下面的代码,但它不工作。请分享在VBA中编写素数的更合适的代码 Private Sub cmdPrime_Click() Dim p, n, i As Integer p = 1 Print “Prime Numbers are : ” For n = 1 To 100 For i = 2 To n – 1 If n Mod i = 0 Then p = 0 Exit For Else p = 1 End If Next If p = 1 Then Print n End If Nex
Private Sub cmdPrime_Click()
Dim p, n, i As Integer
p = 1
Print “Prime Numbers are : ”
For n = 1 To 100
For i = 2 To n – 1
If n Mod i = 0 Then
p = 0
Exit For
Else
p = 1
End If
Next
If p = 1 Then
Print n
End If
Next
End Sub
我猜你是从另一种语言翻译过来的?你真的应该指出哪些线路失败了,你研究了什么
”
:智能引号。这是在应用程序之间进行复制时的典型情况,因此要小心。在visual basic编辑器中使用的语音标记必须是”
,才能进行编译
如果将Option Explicit
放在代码的顶部,那么它会对变量声明和拼写给出很多很好的警告
您只需要输入100,因此Integer
是可以的,但是在本例中Integer
比Long
没有任何优势,因此如果您将来决定超出Integer
的容量,则使用Long
会更安全,从而有溢出的风险。在足够高的上限下,您还需要计算出mod
如果除数(第二个参数)为
在MOD函数中),乘以134217728小于或等于
要计算的数字(MOD中的第一个参数
功能)
微软建议重新使用=number-(INT(数字/除数)*除数)
;我想你可以用CLng
替换INT
,以保持长
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
选项显式
私有子cmdPrime_Click()
变暗p为长,n为长,i为长,i为长
p=1
使用ActiveSheet
.Cells(iCounter+1,1)=“素数为:”'Debug.Print“素数为:
对于n=2到100''<如前所述,1在技术上不是主要btw,因此可以从2开始
对于i=2到n-1
如果n模i=0,则‘如果n-(CLng(n/i)*i)=0,则
p=0
退出
其他的
p=1
如果结束
下一个
如果p=1,则
i计数器=i计数器+1
.Cells(i计数器,1)=n'调试.Print n
如果结束
下一个
以
端接头
为未来读者保留:其他有用的评论来自@ChrisNeilsen
要测试
n
是否为素数,只需测试n
的平方根的可除性。你只需要测试之前检测到的素数的可除性。您甚至可以跳过n
的值,这是一个稍微高效的代码版本。修改了两件事:
a) 因为1是,所以外部循环从2开始
b) 默认情况下,该数字被视为素数。如果它被检测为非素数,则停止进一步的检查。(在公布的代码中,每次检查检测到一个数字为非素数时,都会设置值p=1。每次设置p=1时增加一个计数器,表明它被设置了1059次。)
输出:
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
在复习VBA技能时遇到这个问题。这是我的解决方案,使用算法进行优化,忽略所有偶数和5的除数 我创建了两个模块,用于分离逻辑和实用程序功能。大约在
10秒内打印第一个100000
素数
模块1(素数):
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
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
瞧!素数列表将从单元格A2
打印。
单元格A1
留空,供用户输入,如输入要打印的素数
注意:
我使用了Long
数据类型来覆盖更多的值,而不是Integer
。如果需要打印的值多于2147483647
,则只需将Long
替换为PrimeNumber
模块中的Double
。如果使用Double
数据类型,您将看到显著的性能下降
PS:确保使用链接提前绑定mscorlib.dll非常感谢您的回复。这个代码现在起作用了。但是,如果我需要excel电子表格中的输出,而不是即时窗口中的输出,该怎么办。你能提供代码吗?@QHarr:你真的想让p
和n
成为变体吗?@AJD我绝对没有。让我看一眼!谢谢。有两点:要测试n是否为素数,只需测试n的平方根。你只需要测试之前检测到的素数的可除性。您甚至可以跳过n@chrisneilsen谢谢我已在中添加了您的评论。我已经看到了Euler项目和Eratosthenes筛的一些很好的实现。非常感谢您的回复。这个代码现在起作用了。但是,如果我需要excel电子表格中的输出,而不是即时窗口中的输出,该怎么办。您可以提供代码吗?您可以将此代码添加到输出i
的行中<代码>单元格(行、列)=i
。然后执行row=row+1
。在开始循环之前初始化行
和列
。从我这里获取+1。
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