• Eular质数筛法


      任意一个正整数k,若k≥2,则k可以表示成若干个质数相乘的形式。

      Eratosthenes筛法中,在枚举k的每一个质因子时,我们都计算了一次k,从而造成了冗余。因此在改进算法中,只利用k的最小质因子去计算一次k。

      而在其基础上改进的Eular筛法,其伪代码为:

    isPrime[] = true
    primeList = []
    primeCount = 0
    For i = 2 .. N
        If isPrime[i] Then
            primeCount = primeCount + 1
            primeList[ primeCount ] = i
        End If 
        For j = 1 .. primeCount
            If (i * primeList[j] > N) Then
                Break
            End If
            isPrime[ i * primeList[j] ] = false
            If (i % primeList[j]) Then
                Break
            End If
        End If
    End For

      与Eratosthenes筛法不同的是,对于外层枚举i,无论i是质数,还是是合数,我们都会用i的倍数去筛。但在枚举的时候,我们只枚举i的质数倍。比如2i,3i,5i,...,而不去枚举4i,6i...,原因我们后面会讲到。

      此外,在从小到大依次枚举质数p来计算i的倍数时,我们还需要检查i是否能够整除p。若i能够整除p,则停止枚举。

      Eular筛法可以保证每个合数只会被枚举到一次,时间复杂度为O(n)。当N越大时,其相对于Eratosthenes筛法的优势也就越明显。

    下面是实现代码:

    int numPrime(int n){
        bool isPrime[1000005];
        for(int i = 0; i< 1000005; i++){
            isPrime[i] = true;
        } 
        int PrimeList[100000];
        int Primecount = 0;
        for(int i = 2; i<= n; i++){
            if(isPrime[i]){
                Primecount++;
                PrimeList[Primecount] = i;
            }
            for(int j = 1; j<= Primecount; j++){
                if(i*PrimeList[j] > n) break;
                isPrime[i*PrimeList[j]] = false;
                if(i%PrimeList[j] == 0 ) break;
            }
        }
    //    for(int i = 1; i<= Primecount; i++) cout << PrimeList[i] << endl;
        return Primecount;
    }
    转载请注明出处:http://www.cnblogs.com/ygdblogs
  • 相关阅读:
    从Unity3D编译器升级聊起Mono
    RxJava系列6(从微观角度解读RxJava源码)
    RxJava系列5(组合操作符)
    RxJava系列4(过滤操作符)
    RxJava系列3(转换操作符)
    RxJava系列2(基本概念及使用介绍)
    RxJava系列1(简介)
    给 Android 开发者的 RxJava 详解
    深入浅出RxJava就这一篇就够了
    android非法字符的判定、表情符号的判定
  • 原文地址:https://www.cnblogs.com/ygdblogs/p/5378743.html
Copyright © 2020-2023  润新知