Prime Number Visual Basic

时间:2015-07-08 20:22:12

标签: vb.net visual-studio-2010 visual-studio

我有一项任务,它说:

您已获得名为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

1 个答案:

答案 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秒内找到了百万分之一的素数,但你无法真正比​​较各机器的性能。