素数的判断方法/go实现

这篇文章会介绍三种判断素数的方法,其中对第一、二种简单介绍,第三种会详细介绍。

特别说明一下, 1不是素数,2是素数。

方法一(也是最容易理解的方法):

    若一个数n(n > 2)不为素数,则自然数集合 => {[2, \sqrt{n}]区间}中,一定有一个自然数可以整除n。

方法二(素数都是不可整除的,而合数一定可以由素数相乘得到)

    若一个数n(n > 2)为素数,则素数集合 => {2, 3, ..., m(m < \sqrt{n})}中的任何素数都不能整除n。

方法三(不是合数即为素数,这里把1排除)

算法流程设计:

    从自然数2开始,在数轴上找到比2大且最小的合数m0,[2, m0]区间中除了2和m0外,其余自然数皆为素数。然后又从m0开始找m1。获取m的方法为,遍历当前 参与比较的素数与自然数n的乘积 中最小的积并将其作为m。自然数n如何实现呢?任意素数的自然数n的初始值都为其本身,如果素数与n的乘积等于m,则n+1。

代码实现:

package main

import (
    "fmt"
    "math"
    "time"
)

type Su struct {
    self uint
    next uint
}

var n uint = 2

var SuList = struct {
    iSu int
    list []*Su
}{
    0,
    []*Su{
        &Su{
            2,
            2,
        },
    },
}

func procSu(e uint) {
    for ; n < e; {
        //获取目前自然数序列增长最小合数
        m := compSu()
        //遍历合数
        iteratorSu(m)
    }
}

func compSu() uint {
    var n = uint(math.MaxInt32)
    var idx []int
    var lastSu int
    for  i := 0; i <= SuList.iSu; i++ {
        var tmpN = SuList.list[i].self*SuList.list[i].next
        if tmpN <= n {
            if tmpN < n {
                idx = append([]int(nil), i)
            } else {
                idx = append(idx, i)
            }
            n = tmpN
        }
    }
    for _, i := range idx {
        SuList.list[i].next++
        lastSu = i
    }
    if SuList.list[lastSu].next-SuList.list[lastSu].self == 1 {
        SuList.iSu++
    }
    return n
}

func appendSu(s uint) {
    SuList.list = append(SuList.list, &Su{
        s,
        s,
    })
}

func updateN(number uint) {
    n = number
}

func iteratorSu(number uint) {
    var i uint = n+1
    for {
        if i < number  {
            appendSu(i)
        } else {
            break
        }
        i++
    }
    updateN(number)
}

func main() {
    s := time.Now()
    procSu(10000)
    for _, v := range SuList.list {
       fmt.Print(v.self, ",")
    }
    fmt.Println()
    fmt.Println(`cost:`, time.Since(s).String())
}

扩展:

如何在方法三的基础上实现并发呢?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章