素數的判斷方法/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())
}

擴展:

如何在方法三的基礎上實現併發呢?

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