求質數總結

來源:互聯網
上載者:User

質數又稱素數。指在一個大於1的自然數中,除了1和此整數自身外,沒法被其他自然數整除的數。
一、判斷一個數是否為質數

首先根據定義,最簡單的判斷一個數n是否為質數的方法,就是從2開始對小於n的所有數,依次判斷是否能整除n,若都不能整除就是質數。

bool IsPrime(int n){if(n == 1)return false;for(int i = 2; i < n; i++)if(n % i ==0)return false;return true;}

我們再稍微改進一下,我們可以先判斷一下2能不能整除n,然後2以上的偶數就不需要再判斷了,因為2不能整除n那麼含有因子2的數肯定也不能整除n。再者,我們根本不需要迴圈到n,若兩個數的乘積為n,那麼肯定有一個因子是小於sqrt(n)的,所以,迴圈的上限可以取sqrt(n)。於是就有:

bool IsPrime(int n){if(n == 2)return true;if(n == 1 || (n & 1))return false;int k = (int)sqrt(n);for(int i = 3; i <= k; i += 2)if(n % i == 0)return false;return true;}

上面是過濾掉了2的倍數,計算量變為原來的二分之一,我們也可以把3的倍數過濾掉,也就是只判斷3是否能整除n,其它3的倍數就不需要判斷了,計算量就可以變為原來的三分之一。也就是只剩6*k+1和6*k+5(k為整數)這些數,因為其他數都含有因子2或3,n若不能被2或3整除,那麼n也不能被6*k,6*k+2,6*k+3,6*k+4這些數整除,就不需要判斷這些數能否整除n了,這樣又減少了判斷量。

bool IsPrime(int n){if((n == 2) || (n == 3))return true;if((n == 1) || ((n & 1) == 0) || ((n % 3) ==0))return false;int k = (int)sqrt(n);int step = 4;for(int i = 5; i <= k; i += step){if(n % i == 0)return false;step = 6 - step;}return true;}

二、找出區間內的所有質數
要求區間內的所有質數,首先可以用以上判斷單個質數的方法挨個尋找,但是太慢了。。。
這類問題主要的就是篩選法了。篩法求質數的主要思想就是,從小到大,當判斷完一個數K是否為質數後,把後面的所有的K的倍數(含因子K)都去掉。

#define N 1000000bool isPrime[N];int i;memset(isPrime, true, sizeof(isPrime));isPrime[1] = false;//篩掉大於2的偶數for(i = 4; i < N; i += 2)         isPrime[i] = false;  int bound = sqrt(N);  //用sqrt(N)以內的質數去篩掉後面含有質數因子的元素  for(i = 3; i <= bound; i += 2)               {//從3開始的奇數,如果是質數就去篩掉以自己為因子的元素,不是質數跳過if(false == isPrime[i]) continue;  int step = i << 1;   //i為質數,則從i*i開始篩,以2*i為步長(因為偶數已被篩掉,小於i*i的非質數,已被小於i的質數篩掉)for(int j = i * i ; j < N ; j += step) //含有質數因子i,篩掉      isPrime[j] = false;            }

若求兩個大數之間的質數,也可以用篩法
如求N1和N2之間的質數1000000000 <= N1 < N2 < 2^32 and 1 < N2 - N1 < 1000000

bool isPrime[1000000];int prime[70000]; //儲存小於65536的質數(可以篩unsigned int範圍內的數),篩法求出int primeCnt;     //小於65536的質數個數int i, j;/*求小於65536的質數,儲存在prime數組中*/int N1 = 100000000;int N2 = 101000000;int D = N2 - N1;memset(isPrime, true, sizeof(isPrime));for(i = 0; i < primeCnt; i++){     int k = N2 % prime[i];     //可知 N2-k 含質因子prime[i],不是質數,N2 - k - x*prime[i](x為整數)都不是質數數,篩掉  int step = prime[i]; int j = D - k; // N2 - k 對應於數組下標 D - k, N2 - k - x * prime[i] 對應於數組下標 j - x * prime[i]; while(j >= 0) {isPrime[j] = false; //isPrime[j] 代表 N1 + j 是否是質數j -= step; }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.