判断质数与筛质数

  

  一:判定质数

  要判断一个数是不是质数,只需遍历小于等于它的所有数,如果它能被除了1和本身之外的数整除,那么它就不是质数。

很简单,暴力枚举,代码如下:

1 bool is_prime(int x)
2 {
3     if (x < 2) return false;
4     for (int i = 2; i < x ; i ++ )
5         if (x % i == 0)
6             return false;
7     return true;
8 }

但是还可以优化,对于一个数x,它有一个约数d,那么x/d也是x的约数,所以我们只需要枚举较小的一个就可以了,即d < x/d ,即我们只需枚举到√x即可。

1 bool is_prime(int x)
2 {
3     if (x < 2) return false;
4     for (int i = 2; i <= x / i; i ++ )
5         if (x % i == 0)
6             return false;
7     return true;
8 }

时间复杂度就从原本的O(n)降为了O(√n)。

   

      二:分解质因数

由上面,我们知道x中最多只包含一个大于√x的质因子,如果有两个就大于x了,矛盾。所以我们先枚举小于等于√x的质因子,再特判一下大于√x的质因子即可。代码如下:

 1 void solve(int n){
 2     for(int i = 2; i <= n / i ; i ++)
 3     {
 4         if( n % i == 0){
 5             int s = 0;
 6             while(n % i == 0){
 7                 n /= i;
 8                 s ++;
 9             }
10             cout << i << " " << s << endl;
11         }
12     }
13     if(n != 1)cout << n << " " << 1 << endl;
14 }

 

   三:(1)筛法求质数

思想是,将2~n之间的数枚举,从前往后,依次将每一个数的倍数筛掉,用一个primes数组存储质数,代码如下:

 1 void get_primes(int n)
 2 {
 3     for (int i = 2; i <= n; i ++ )
 4     {
 5         if (st[i]) continue;
 6         primes[cnt ++ ] = i;
 7         for (int j = i; j <= n; j += i)
 8             st[j] = true;
 9     }
10 }

当i = 2,循环n / 2次, 当i = 3 ,循环n / 3次。所以一共循环n / 2 + n / 3 + n / 4 + ....n / n = n(1 / 2 + 1 / 3 + 1 / 4 + ... 1 / n),当n趋于无穷时,调和级数趋于lnn + c。

所以该算法的时间复杂度为O(nlogn)。这个复杂度是计算将每一个数的倍数筛掉的时间复杂度,而代码中的只将素数的倍数筛掉的复杂度会更低一些,为O(nloglogn)。

(1 ~ n 中有n / lnn 个素数)。

  

  (2)线性筛法:

 1 void get_primes(int n)
 2 {
 3     for (int i = 2; i <= n; i ++ )
 4     {
 5         if (!st[i]) primes[cnt ++ ] = i;
 6         for (int j = 0; primes[j] <= n / i; j ++ )
 7         {
 8             st[primes[j] * i] = true;
 9             if (i % primes[j] == 0) break;
10         }
11     }
12 }

将每一个质数加入,然后该质数去筛掉该质数的倍数。当i % primes[j] == 0时,primes[j]一定是i * primes[j]的最小质因子,也一定是i的最小质因子。当i % primes[j] != 0时,说名primes[j]小于i的所有质因子,所以primes[j]也一定是primes[j] * i的最小质因子。对于一个合数x,假设primes[j]是他的最小质因子,当i枚举到x / primes[j]的时候,(x / primes[j]一定比x先枚举到),x就会在循环内被筛掉。由于每一个数只有一个最小质因子,所以是线性的。

 

猜你喜欢

转载自www.cnblogs.com/1-0001/p/11948829.html