一、试除法求素数
(通常会超时)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | bool isPrime(int n){        for(int i = 2; i <= sqrt(n); i++){            if(n%i==0)                return false;        }        return true;    }    int countPrimes(int n) {        if(n == 0 || n == 1)            return 0;        int cnt = 0;        for(int i = 2; i < n; i++){            if(isPrime(i))                cnt++;        }        return cnt;    }
  | 
 
二、埃氏筛(厄拉多塞筛法)
可以计算n<=10^7的数
1 2 3 4 5 6 7 8 9 10 11 12 13
   | int countPrimes(int n) {        vector<bool>vis(n,false);        int cnt = 0;        for(int i = 2; i < n; i++){            if(!vis[i]){                cnt++;                for(int j = i+i; j < n; j += i){                    vis[j] = true;                }            }        }        return cnt;    }
  | 
 
预处理素数筛:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
   | const mx = 1000 
  var primes = []int{0} 
  func init() {  	isPrime := [mx]bool{} 	for i := 2; i < mx; i++ { 		if !isPrime[i] { 			primes = append(primes, i) 			for j := i * i; j < mx; j += i { 				isPrime[j] = true 			} 		} 	} 	fmt.Println(primes)  }
   | 
 
三、线性筛(欧拉筛)
在数据量比较大的时候,线性筛的效率更高。
算法思想:每个合数只被划掉一次,因此划去  每个数x 乘上<=x的最小质因子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   | const mx = 1e6 + 1
  var primes = make([]int, 0)
  func init() { 	isPrime := [mx]bool{} 	for i := 2; i < mx; i++ { 		if !isPrime[i] { 			primes = append(primes, i) 		} 		for _, p := range primes { 			if i*p >= mx { 				break 			} 			isPrime[i*p] = true 			if i%p == 0 {  				break 			} 		} 	} }
   |