质数
1.定义 质数是指在大于
1
1
1 的自然数中,除了
1
1
1 和它本身以外不再有其他因数的自然数。
2.如何来判断一个数是否是质数
- 2.1.1 试除法 ------
O
(
n
)
O(n)
O(n)
枚举从 2 {2} 2 到 n − 1 {n-1} n−1 的所有数,判断其中是否含有 n {n} n 的因子,也就是( n n n % i i i == 0 0 0),不难看出这样的时间复杂度是 O ( n ) O(n) O(n) 。
bool is_prime(int n)
{
for (int i = 2; i < n; i ++ )
{
if (n % i == 0)return false;
}
return true;
}
- 2.1.2 试除法的优化 ------ O ( n ) O(\sqrt{n}) O(n)
- 如果
d
d
d |
n
n
n, 那么
n
d
\frac{n}{d}
dn |
n
n
n 。
证明:如果 d d d 是 n n n 的因子,那么令 k = n / d k = n / d k=n/d 因为 k ∗ d = n k * d=n k∗d=n 所以 k k k 也是 n n n 的因子,所以 n / d n/d n/d 也是 n n n 的因子。
因此,我们不难发现 d d d 和 n d \frac{n}{d} dn 总是成对出现的。所以我们只要枚举较小的那一部分因子即可,也就是让 d ≤ n / d d \leq n/d d≤n/d 或者是 d ∗ d = n d * d = n d∗d=n,也就是 d ≤ n d \leq \sqrt{n} d≤n 这样的话就把时间复杂度减少到了 O ( n ) O(\sqrt{n}) O(n) 。
注:for循环内部 如果写成 d ≤ n d \leq \sqrt{n} d≤n,这样循环每次都会算一遍 n \sqrt{n} n ,这样的话效率太低,如果写成 d ∗ d = n d * d = n d∗d=n, d ∗ d d*d d∗d 有可能会爆int的范围,比如当 n = 2147483647 ( i n t 的 最 大 值 ) n = 2147483647(int的最大值) n=2147483647(int的最大值)时, d ∗ d d*d d∗d就会超出 i n t int int的范围,从而导致结果出错。所以我们一般写成 i = n / i i = n / i i=n/i 。
bool is_prime(int n)
{
for (int i = 2; i <= n / i; i ++ )
{
if (n % i == 0)return false;
}
return true;
}