这篇文章会介绍三种判断素数的方法,其中对第一、二种简单介绍,第三种会详细介绍。
特别说明一下, 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())
}
扩展:
如何在方法三的基础上实现并发呢?