因此我们可以从
2
2
2枚举到
i
−
1
i-1
i−1,如果
i
m
o
d
  
当
前
枚
举
的
数
=
0
i \mod 当前枚举的数=0
imod当前枚举的数=0则说明
i
i
i的因数不只有
1
1
1和
i
i
i,因此可以判断
i
i
i为合数。反之,如果除去
1
1
1和
i
i
i之外的其它数都不可以整除
i
i
i,则可以判定
i
i
i为质数。
时间复杂度:
O
(
n
)
O(n)
O(n),其中n为判定的数。
方法二
发现对于一个数
i
i
i,如果
i
=
a
∗
b
i=a*b
i=a∗b,则
a
a
a与
b
b
b中必然至少有一个数小于等于
i
\sqrt{i}
i。
因此我们可以得出,如果在
[
2
,
i
]
[2,\sqrt{i}]
[2,i]中找不到
i
i
i的因数,那么
[
i
+
1
,
i
−
1
]
[\sqrt{i}+1,i-1]
[i+1,i−1]中必然也不会有
i
i
i的因数。
因此把方法一改进一下,就可以做到
O
(
n
)
O(\sqrt{n})
O(n)的时间复杂度。
优化
有一个与它有关的重要定理:大于等于
5
5
5的一组素数肯定是
6
x
−
1
6x-1
6x−1或
6
x
+
1
6x+1
6x+1的形式,其中
x
x
x为正整数。
证明可以从一个大于3的素数的因数不包含
2
2
2、
3
3
3来考虑。
设待判定的数为
i
i
i,我们先判断
2
2
2,
3
3
3是不是
i
i
i的真因子,如果是就直接判为合数。
否则,则
i
i
i必含有
>
=
5
>=5
>=5的质因子,我们枚举
6
x
−
1
6x-1
6x−1与
6
x
+
1
6x+1
6x+1即可。
这样可以使时间复杂度缩小6倍。(尽管好像没什么卵用)
筛法
筛法的不同之处在于,它一般会把所有素数筛出来,因此它的时间复杂度会比较高,但在需要得知
[
1
,
n
]
[1,n]
[1,n]中的素数时,筛法占有绝对的优势。
那些
O
(
n
2
)
、
O
(
n
n
)
O(n^2)、O(n \sqrt{n})
O(n2)、O(nn)的鬼畜筛,以及
O
(
n
2
3
)
O(n^\frac{2}{3})
O(n32)的神仙筛这里并不提及。
我们考虑一个合数
x
x
x=
i
∗
j
i*j
i∗j,其中
j
j
j为素数,我们要证明
i
i
i与
j
j
j的组合不会被break掉当且仅当
j
j
j为
x
x
x的最小质因子。
考虑反证法。
如果
j
j
j不是最小质因子,设
x
x
x的最小质因子为
k
k
k,则
i
m
o
d
  
k
=
0
i \mod k=0
imodk=0,因为有上面那条break语句的存在,所以我们第二重循环在枚举到素数
k
k
k时就会被break掉,根本不会枚举到
j
j
j。
因此一个数只会被筛一次,又因为这个二重循环每一次必然会筛掉一个数,所以时间复杂度是线性的,
O
(
n
)
O(n)
O(n)。