使用Prime Number程序.NET的难度

时间:2014-01-29 18:10:45

标签: .net vb.net

我正在尝试编写一个程序,如果您输入一个数字并单击一个按钮,该程序将能够确定该数字是否为素数(只能被1和它本身整除)。

当我输入数字“5”(例如)时,程序声明“是”它是素数。但是,当我输入“4”(不是素数)时,程序仍然表示是素数。

根据我写的“If”语句和循环,我不确定哪里出错了。我的代码如下:

Public Class Form1
    Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
        Dim iNum, iSum As Double
        Dim isPrime As Boolean = True
        iNum = Convert.ToInt32(tbxN.Text)
        For i = 2 To (iNum - 1) Step 1
            iSum = iNum Mod i
        Next
        If iSum = 0 Then
            isPrime = False
            lblAnswer.Text = "No"
        Else
            isPrime = True
            lblAnswer.Text = "Yes"
        End If
    End Sub
End Class

我认为这可能是我的“If”语句的一个问题,并且程序只使用循环中的最后一个值来做出素数决定,但是,我需要它,如果iSum是EVER 0,那么它不是Prime。如果iSum永远不是0,那么它就是Prime。

我该如何解决这个问题?谢谢!

5 个答案:

答案 0 :(得分:3)

您需要修改逻辑,当前逻辑会覆盖iSum的值,从而导致错误结果。一旦发现iSum0,就应该打破循环,否则布尔变量isPrime将保持为假。 (我还在初始化时将变量isPrime更改为false)

Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
    Dim iNum, iSum As Double
    Dim isPrime As Boolean = False
    iNum = Convert.ToInt32(tbxN.Text)
    For i = 2 To (iNum - 1) Step 1
        iSum = iNum Mod i
        If (iSum = 0) Then
            isPrime = True
            Exit For
        End If
    Next
    If isPrime Then
        lblAnswer.Text = "Yes"
    Else
        lblAnswer.Text = "No"
    End If
End Sub

此外,您可以通过检查代码来进一步优化代码,直到iNum / 2代替iNum - 1,或者甚至更好(如评论中指出的那样)进行检查直到该数字的平方根:

For i = 2 To Math.Sqrt(iNum) Step 1

有关Wikipedia

的更多信息

答案 1 :(得分:1)

检测数字是否为素数的算法不正确:

For i = 2 To (iNum - 1) Step 1
    iSum = iNum Mod i
Next
If iSum = 0 Then
    isPrime = False
    ...

它假设如果一个数字是非素数,它将被2..N-1范围内的所有数字整除。非素数的实际要求可以被此范围内的任何数整除。

要实现此功能,请检查iNum Mod i是否为零,并在看到后立即停止循环。当iNum Mod i为零时,设置一个标记为“非素数”的标记。如果您的循环完成而没有达到上述条件,则该数字为素数。

请注意,您不必检查2..N-1范围内的所有数字:如果您通过数字从2到N的平方根,包括在内,并且您没有找到任何除数,你知道这个数字是素数。

答案 2 :(得分:0)

你也不需要总结任何东西,如果你在[2,sqrt(p)]范围内得到p mod x == 0,这意味着p不是素数并停止cicle并返回。

答案 3 :(得分:0)

如果你只想要一些有用的东西,这一切都很好。但是,如果你想要更有效的东西,Eratosthenes筛子的效果非常好。这是一个生成bitarray的函数,其中索引为prime的每个元素都为true,其余元素为false。这对于一次使用非常有效,或者对于重复使用甚至更有效。生成1,000,000个元素数组大约需要3毫秒。

Dim Primes As BitArray
Primes = GeneratePrimes(1000000)
Dim IsPrime As Boolean = Primes(20)

Function GeneratePrimes(n As Integer) As BitArray
    Dim bits = New BitArray(n + 1, True)
    Dim max = CInt(Math.Sqrt(n))
    bits(0) = False
    bits(1) = False
    For i As Integer = 2 To max
        If bits(i) Then
            For j As Integer = i * i To n Step i
                bits(j) = False
            Next
        End If
    Next
    Return bits
End Function

正如您所看到的那样,索引处元素的检查值返回true或false。

答案 4 :(得分:0)

所有提到平方根的人都是正确的,30%。你只需要检查平方根+ 1(为了好的衡量标准),但实时节省的是你只需要将数字除以所有PRIMES直到平方根+ 1。

e.g。 要找出23是否是素数,你将除以素数除以平方根+ 1。

sqrt(23) = 4.79 so we go to > 5

23 mod 2 = 1,
23 mod 3 = 2, 
23 mod 5 = 3,
23 = prime

因为没有模数计算= 0