素數

素數

@(算法)

素數簡介

質數(prime number)又稱素數。
質數定義爲在大於1的自然數中,除了1和它本身以外不再有其他因數。還能被其他數(0除外)整除的數爲合數。

判斷一個數是否是素數
根據定義,除了1和本身之外沒有其他約束,
所以判斷是否爲質數,
根據定義直接判斷從2到n-1是否存在n的約數。

方法一:暴力破解!

bool isPrime(int num){
    for(int i=2;i<num;i++){
        if(num%i ==0){
            return 0;
        }
    }
    return 1;
}

上述方法,明顯存在效率極低的問題。
一個數若可以進行因式分解,那麼分解時得到的兩個數,一定
是一個小於等於sqrt(n),一個大於等於sqrt(n)

改進:

bool isPrime(int num){
    int t=sqrt(num);
    for(int i=2;i<num;i++){
        if(num%i ==0){
            return 0;
        }
    }
    return 1;
}

方法二:素數篩法

可以提前處理出來1~n 的全體素數
1.把1~n列出來
2.去掉不是特殊的1
3.從小到大,枚舉每一個沒有刪掉的數字i把 i 的2倍,3倍,4倍,...,刪掉剩下的沒被刪掉的都是素數
const int N=100;
int notprime[N];
int main(){
    notprime[1]=1;
    for(int i=2;i<N;i++){
        if(notprime[i]==0){
            for(int j=i+i;j<N;j=j+i){    ////刪掉2*i,3*i,4*i......
                notprime[j]=1;
            }
        }
    }
    for(int i=1;i<N;i++){
        if(notprime[i]!=1){
            printf("%d\t",i);
        }
    }
    return 0;
}

方法三:歐拉篩法

在素數篩法中,有很多合數被刪除多次。而歐拉篩法提供兩個數組,一個是素數表,另一個是刪除合數表(值爲1表示表示不是素數)。
const int N=100;
int notprime[N];    //刪除標記,值爲1表示表示不是素數
int prime[N];   //素數表
int main(){
    int t=0;  //初始化素數表爲空
    notprime[1]=1;
    for(int i=2;i<N;i++){
        if(notprime[i]==0){     //找到一個沒有被刪除的數
            prime[t++]=i;       //加入素數表
        }
        for(int j=0;j<t&&prime[j]*i<N;j++){ //枚舉素數表
            notprime[prime[j]*i]=1;
            if(i%prime[j]==0){
                break;      //保證了每個合數只會被它的最小素因子篩掉
            }
        }
    }
    for(int i=0;i<N;i++){
        if(prime[i]!=0){
            printf("%d\t",prime[i]);
        }
    }
}

prime[]數組中的素數是遞增的,當i能整除prime[j],那麼 prime[j]*i 這個合數肯定被prime[j]乘以某個數篩掉。i%prime[j]==0保證了每個合數只會被它的最小素因子篩掉。

參考
[1]http://www.cnblogs.com/zhuoha...
[2]http://www.cnblogs.com/zhuoha...
[3]https://baike.baidu.com/item/...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章