(C ++コードを含む)素数の概要を決定するいくつかの方法

素数が定義されています

素数としても知られている(素数)、素数は、番号1は、それ自身の性質および1よりも数因子大きいに指します。29 2〜29の唯一の要因である素数である;例えば、素数は、二つの唯一の要因である2、1及び2で51は素数ではない、1及び51 3及び17に加えて、それは、2つの要因があるので、その51ある合成数

二、素数判断方法

正の整数n(≧2)与えられました:

方法1.定義

残りはその後オペランドがので、数Nの要因であること、ということ0でnは素数でない場合は、Nで割った、程度である[2、N-1]のすべての整数の。コードは以下の通りであります:

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

向上のためのメソッドを定義します。2.

因子以来N常にペアで現れ、1〔に分布しています、 n個 \ nはSQRT ]と[ n個 \ nはSQRT 、N]の範囲(数Ruoyin n個 \ nはSQRT 2つのリピート因子として私たちは)、我々は唯一の範囲を決定する必要があります。コードは以下の通りであります:

bool isPrime2(int n){
 bool yes=true;
 for(int i=2;i<=sqrt(n);i++){
  if(n%i==0){
   yes=false;
   break;
  }
 }
 return yes;
}

3.メソッドを法

nの式場合n≥6が、N、次に、6X + 1,6x + 2,6x + 3,6x + 4,6x + 5,6x(X≧1)中のように表すことができるので、場合6X + 2,6x + 4または6X、Nは素数ではないことは明らかである; nは6×+ 1発現または6X + 5である場合、したがって、それは素数、次いで、塗布法もよいです。コードは以下の通りであります:

bool isPrime3(int n){
 bool yes=false;
 if(n==2||n==3||n==5){ //当n<6时列举即可
  yes=true;
 }
 else if(n%6==1||n%6==5){ //通过判断余数的方式来判断n的表达式
  yes=true;
  for(int i=2;i<=sqrt(n);i++){
   if(n%i==0){
    yes=false;
    break;
   }
  }
 }
 return yes;
}

テスト、時間を消費

### 4.筛选法(Eratosthenes筛选)
我们可以很容易的判断出2、3、5等较简单的数是素数,而且,当一个数是素数后,它的倍数一定为合数。因此,我们可以将一定范围的整数筛选掉合数,剩下的即是素数。代码如下:

```cpp
bool isPrime4(int n){
 bool yes=false;
 //先生成一定范围的整数表,再应用筛选法,得到素数表,最后与素数表比对
 //生成0~100000内的素数表
 int num[100000]={0}; //0表示素数,1表示合数
 for(int i=2;i<100000;i++){
  if(!num[i]){
   for(int j=i+i;j<100000;j+=i){
    num[j]=1;
   }
  }
 }
 if(!num[n]){
  yes=true;
 }
 return yes;
}

5.改善されたスクリーニング

まず第一に、私たちは必ず2を除くすべての素数は奇数であることをすることができ、それは、奇数列2よりも大きいの手段を確立することが可能であるので、両方の判断を拡大するだけでなく、裁判官の数を減らすこと、及び、その後、我々は3、5の奇数列を取得し、 7,9 ......、一例として図3に示すように、この方法によれば、我々は、選別されるべきである4 3×2,3×3,3×4 ......が、3×2,3×4 ......偶数である場合、選別された、及び5の倍数をスクリーニングする際にこのようのみ、3×3,3×5,3×7アウト画面、3×3から始まる......、同じ5×2で始めるべきであるが、5×2,5×4 ...... 5×7,5×9を選別するので、スクリーニングは5×5の5の倍数でなければなりません、でも、あなたは5×3、5×3から始めて検討する必要がありますが、すでに3の倍数を遮蔽でふるい始めています私たちは、フィルタグループの数を観察するとき......、などAルールがあります:素数ならば、アウト×、画面からフィルタが開始さ×+ 2×A× I(私は0,1 =、 2 ......)。
開始画面から×理由:4我々は×2を選別しなければならない方法によって、×3、 ×4 ...... ×2、×4 ......偶数、選別されたされ、そしてAから3の倍数をスクリーニングする場合、開始×3フィルタは、> 3は、確かに、この3×数で選別された場合と、その後、フィルタは×5、同じトークン、起動した場合は> 5、その後、フィルタ5 ×スクリーニング始まりそうになるまで、それが選別される前に処理されませんでした。倍数は5×のこの数を選別されたとき。
なぜ画面アウト×+ 2×A× I(iは0,1,2 ...... =)?私たちは、変換式を見ることができます:×+ 2× ××私は(+ 2×i)を=。スクリーニングは、×(+ 0)×うち、画面から起動時ことが分かる ×(+ 2)×(+ 4)...... 前の手順の法律に沿っ。
上記のプロセスは、コードのように要約されます:

bool isPrime5(int n){
 bool yes=false;
 int num[100000]={0}; //生成3~2*99999+3范围内的奇数数组
 //先判断当n=2时的情况
 if(n==2){
  yes=true;
 }
 else{
  for(int i=0;i<100000;i++){
   if(!num[i]){
    for(int j=(2*i+3)*(2*i+3);j<(2*100000+3);j+=2*(2*i+3)){
     num[(j-3)/2]=1;
    }
   }
  }
 }
 if((n-3)%2==0){
  if(!num[(n-3)/2]){
   yes=true;
  }
 }
 return yes;
}

第三に、要約

次のように上記の方法は、一緒に入れています。

#include <iostream>
#include <math.h>
#include <time.h>
#define SIZE 10000
using namespace std;
bool isPrime(int n) {
 bool yes = true;
 for (int i = 2; i < n; i++) {
  if (n % i == 0) {
   yes = false;
   break;
  }
 }
 return yes;
}
bool isPrime2(int n) {
 bool yes = true;
 for (int i = 2; i <= sqrt(n); i++) {
  if (n % i == 0) {
   yes = false;
   break;
  }
 }
 return yes;
}
bool isPrime3(int n) {
 bool yes = false;
 if (n == 2 || n == 3 || n == 5) {
  yes = true;
 }
 else if(n%6==1||n%6==5) {
  yes = true;
  for (int i = 2; i <= sqrt(n); i++) {
   if (n % i == 0) {
    yes = false;
    break;
   }
  }
 }
 return yes;
}
bool isPrime4(int n) {
 bool yes = false;
 int num[SIZE] = { 0 };
 for (int i = 2; i < SIZE; i++) {
  if (!num[i]) {
   for (int j = i + i; j < SIZE; j += i) {
    num[j] = 1;
   }
  }
 }
 if (!num[n]) {
  yes = true;
 }
 return yes;
}
bool isPrime5(int n) {
 bool yes = false;
 int num[SIZE] = { 0 };
 if (n == 2) {
  yes = true;
 }
 else {
  for (int i = 0; i < SIZE; i++) {
   if (!num[i]) {
    for (int j = (2 * i + 3) * (2 * i + 3); j < (2 * SIZE + 3); j += 2 * (2 * i + 3)) {
     num[(j - 3) / 2] = 1;
    }
   }
  }
 }
 if ((n - 3) % 2 == 0) {
  if (!num[(n - 3) / 2]) {
   yes = true;
  }
 }
 return yes;
}
int main() {
 cout << "function isPrime():" << endl;
 time_t before = clock();
 for (int i = 2, j = 0; i < 10000; i++) {
  if (isPrime(i)) {
   cout << i << " ";
   j++;
  }
  if (j == 9) {
   cout << endl;
   j = 0;
  }
 }
 time_t after = clock();
 cout << endl;
 cout << static_cast<double>((after - before) * 1000 / CLOCKS_PER_SEC) << "(ms)" << endl;
 cout << "function isPrime2():" << endl;
 before = clock();
 for (int i = 2, j = 0; i < 10000; i++) {
  if (isPrime2(i)) {
   cout << i << " ";
   j++;
  }
  if (j == 9) {
   cout << endl;
   j = 0;
  }
 }
 after = clock();
 cout << endl;
 cout << static_cast<double>((after - before) * 1000 / CLOCKS_PER_SEC) << "(ms)" << endl;
 cout << "function isPrime3():" << endl;
 before = clock();
 for (int i = 2, j = 0; i < 10000; i++) {
  if (isPrime3(i)) {
   cout << i << " ";
   j++;
  }
  if (j == 9) {
   cout << endl;
   j = 0;
  }
 }
 after = clock();
 cout << endl;
 cout << static_cast<double>((after - before) * 1000 / CLOCKS_PER_SEC) << "(ms)" << endl;
 cout << "function isPrime4():" << endl;
 before = clock();
 for (int i = 2, j = 0; i < 10000; i++) {
  if (isPrime4(i)) {
   cout << i << " ";
   j++;
  }
  if (j == 9) {
   cout << endl;
   j = 0;
  }
 }
 after = clock();
 cout << endl;
 cout << static_cast<double>((after - before) * 1000 / CLOCKS_PER_SEC) << "(ms)" << endl;
 cout << "function isPrime5():" << endl;
 before = clock();
 for (int i = 2, j = 0; i < 10000; i++) {
  if (isPrime5(i)) {
   cout << i << " ";
   j++;
  }
  if (j == 9) {
   cout << endl;
   j = 0;
  }
 }
 after = clock();
 cout << endl;
 cout << static_cast<double>((after - before) * 1000 / CLOCKS_PER_SEC) << "(ms)" << endl;
 return 0;
}

私たちは、コード(動作環境:vs2019、デバッグ、x64の)を実行します、時間のかかる結果は次の通りです
isPrimeは():379ms
370ms:isPrime2()
isPrime3を():400msの
1008ms:isPrime4()
isPrime5を():1028ms
プロセスの発見効率を2最高。Iが最適化されるコードであってもよい、方法3の効率が高くありません。方法4と5氏とテーブルの方法は、消費時間が増加し、素数である必要があり、その後、比較すること。表は、素数を生成することである場合、整数が素数か否かが判定され、二つの方法の効率は比較的高くてもよいです。前記大きな素数テーブルの範囲を生成する方法。

リリース元の2件の記事 ウォンの賞賛0 ビュー326

おすすめ

転載: blog.csdn.net/alazyperson/article/details/104083695