我有一项任务,它说:
您已获得名为Prime的工作程序 它有一个输入,它是一个整数 按下“查找素数”按钮时,将识别第n个素数。
例如:
如果输入4并单击该按钮,则显示响应为“第4个素数为7”。如果输入9,则显示响应为“第9个素数为23”。
该程序100%准确,正确定位第n个素数 当您尝试查找更大的素数时会出现问题。
例如:
如果输入10000并单击该按钮,则显示响应为“第10000个素数为104729”。这是正确的答案;但是,我的i7计算机花了48秒才找到解决方案。想象一下,找到第一百万个素数需要多长时间。您的任务是分析问题,找到一个更有效的解决方案,使程序更有用。首先,您必须了解提供的代码是如何工作的。本文档末尾有一个练习。您将使用它来手动运行代码。一旦了解了它的工作原理,就可以分析找到素数的问题,以使程序更有效地运行。程序对于大数字来说很慢的原因是因为我进行了大量不必要的计算。不是你必须使用自己的代码。您不能使用任何预先构建的素数例程,函数或库;这样做会导致分配为零。思考真正需要做的是解决这个问题的方法。
他说最好的方法是使用数组,但我不知道如何使用数组来解决这个问题。他还说要将除法(mod)保持在最低限度以及if语句。
以下是他为我们提供的代码:
Option Strict On
Public Class Form1
Private Sub PositionBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PositionBox.TextChanged
If IsNumeric(PositionBox.Text) Then
If Decimal.Parse(PositionBox.Text) >= 1 Then
FindPrimeBtn.Enabled = True
Else
FindPrimeBtn.Enabled = False
End If
Else
FindPrimeBtn.Enabled = False
End If
End Sub
Private Sub FindPrimeBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FindPrimeBtn.Click
Dim FinalPosition As Long
Dim FinalPrime, Even As Long
Dim Number As Long = 2
Dim CurrentPosition As Long = 1
Dim elapsed As System.TimeSpan
Dim sw As Stopwatch = New Stopwatch()
sw.Start() 'starts the clock
Dim IsPrime As Boolean
FinalPosition = Long.Parse(PositionBox.Text)
Even = CurrentPosition Mod 2
While (CurrentPosition > 2 And Even <> 0)
IsPrime = True
End While
While (CurrentPosition <= FinalPosition)
IsPrime = True
For x = 2 To Number - 1
If Number Mod x = 0 Then
IsPrime = False
End If
Next
If IsPrime Then
FinalPrime = Number
CurrentPosition += 1
End If
Number += 1
End While
elapsed = sw.Elapsed() 'captures the elapsed time it took to compute the result
ResultLbl.Text = "The " + FinalPosition.ToString() + "th is " + FinalPrime.ToString()
ElapsedTimeLbl.Text = "Elapsed time is " + elapsed.ToString()
End Sub
End Class
答案 0 :(得分:1)
退房 this article 特别是,它说: 通过仅选择素数作为候选因子,可以减少的努力。此外,试验因素只需要\ scriptstyle \ sqrt {n},因为如果n可以被某个数字p整除,则n = p×q,如果q小于p,则n先前被检测为可以被q或q的素因子整除。
我认为他希望你存储在数组中找到的素数,然后遍历数组中的素数集,而不是迭代每个或每个奇数。
不确定他是否允许你导入system.math,其中平方根函数是,但是会加速它。我想你可以问......
无论如何,我没有使用存储的找到的素数数组,并且不喜欢他所有的变量名,但是如果它有帮助,我正在使用它:
Option Strict On
Imports System.Math
Public Class Form1
Private Sub PositionBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PositionBox.TextChanged
If IsNumeric(PositionBox.Text) Then
If Decimal.Parse(PositionBox.Text) >= 1 Then
FindPrimeBtn.Enabled = True
Else
FindPrimeBtn.Enabled = False
End If
Else
FindPrimeBtn.Enabled = False
End If
End Sub
Private Sub FindPrimeBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FindPrimeBtn.Click
Dim CurrentprimeSequence As Long = 1
Dim FinalprimeSequence As Long
Dim prime_possible As Double = 2
Dim foundPrime As Double
Dim test_div As Double
'Dim Even As Long
Dim elapsed As System.TimeSpan
Dim sw As Stopwatch = New Stopwatch()
sw.Start() 'starts the clock
Dim IsPrime As Boolean
FinalprimeSequence = Long.Parse(PositionBox.Text)
'Even = CurrentprimeSequence Mod 2
'While (CurrentprimeSequence > 2 And Even <> 0)
' IsPrime = True
'End While
FindPrimeBtn.Enabled = False
While (CurrentprimeSequence <= FinalprimeSequence)
IsPrime = True ' until proven false
test_div = 2
Do While IsPrime And (test_div <= Sqrt(prime_possible))
IsPrime = (prime_possible Mod test_div > 0)
test_div = test_div + 1 - CDbl(test_div > 2) ' skip odd numbers after 2
'If test_div = 2 Then
' test_div = test_div + 1
'Else
' test_div = test_div + 2
'End If
Loop
'For test_div = 2 To Sqrt(prime_possible) ' test if divisible by any number two to square root of candidate, skip even #s
' If prime_possible Mod test_div = 0 Then
' IsPrime = False
' Exit For ' or change to while isprime and (test_div < prime_possible)
' End If
'Next
If IsPrime Then
foundPrime = prime_possible
If CurrentprimeSequence Mod 100000 = 0 Then
Debug.Print(CStr(CurrentprimeSequence) + " " + CStr(foundPrime) + " " + sw.Elapsed().ToString)
End If
CurrentprimeSequence += 1
End If
prime_possible += 1
End While
elapsed = sw.Elapsed() 'captures the elapsed time it took to compute the result
ResultLbl.Text = "The " + FinalprimeSequence.ToString() + "th is " + foundPrime.ToString()
ElapsedTimeLbl.Text = "Elapsed time is " + elapsed.ToString()
FindPrimeBtn.Enabled = True
End Sub
End Class
在我的电脑上,它在大约28秒内找到了百万分之一的素数,但你无法真正比较各机器的性能。