這篇文章會介紹三種判斷素數的方法,其中對第一、二種簡單介紹,第三種會詳細介紹。
特別說明一下, 1不是素數,2是素數。
方法一(也是最容易理解的方法):、
若一個數n(n > 2)不爲素數,則自然數集合 => {[2, ]區間}中,一定有一個自然數可以整除n。
方法二(素數都是不可整除的,而合數一定可以由素數相乘得到)
若一個數n(n > 2)爲素數,則素數集合 => {2, 3, ..., m(m < )}中的任何素數都不能整除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())
}
擴展:
如何在方法三的基礎上實現併發呢?