web-dev-qa-db-ja.com

1から100までの素数の印刷

このc ++コードは、次の素数を出力します。5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 61 71 71 79 79 83 89 97。

しかし、私はそれが私の本が書かれることを望んでいるとは思わない。数値の平方根について言及しています。そこで、2番目のループをfor (int j=2; j<sqrt(i); j++)に変更してみましたが、必要な結果が得られませんでした。

このコードを私の本が望むように変更するにはどうすればよいですか?

int main () 
{
    for (int i=2; i<100; i++) 
        for (int j=2; j<i; j++)
        {
            if (i % j == 0) 
                break;
            else if (i == j+1)
                cout << i << " ";

        }   
    return 0;
}

素整数とは、正確に2つの異なる除数、つまり1と数値自体を持つものです。 100未満のすべての素数を見つけて出力するC++プログラムを作成、実行、およびテストします。(ヒント:1は素数です。2〜100の各数について、Remainder = Number%nを見つけます。nは2からの範囲です。 to sqrt(number)。nがsqrt(number)よりも大きい場合、その数はnで割り切れない。なぜ?剰余が0に等しい場合、その数は素数ではない。)

13
Sahat Yalkabov

3つの方法:

1。

int main () 
{
    for (int i=2; i<100; i++) 
        for (int j=2; j*j<=i; j++)
        {
            if (i % j == 0) 
                break;
            else if (j+1 > sqrt(i)) {
                cout << i << " ";

            }

        }   

    return 0;
}

2。

int main () 
{
    for (int i=2; i<100; i++) 
    {
        bool prime=true;
        for (int j=2; j*j<=i; j++)
        {
            if (i % j == 0) 
            {
                prime=false;
                break;    
            }
        }   
        if(prime) cout << i << " ";
    }
    return 0;
}

3。

#include <vector>
int main()
{
    std::vector<int> primes;
    primes.Push_back(2);
    for(int i=3; i < 100; i++)
    {
        bool prime=true;
        for(int j=0;j<primes.size() && primes[j]*primes[j] <= i;j++)
        {
            if(i % primes[j] == 0)
            {
                prime=false;
                break;
            }
        }
        if(prime) 
        {
            primes.Push_back(i);
            cout << i << " ";
        }
    }

    return 0;
}

編集:3番目の例では、以前に計算されたすべての素数を追跡します。数が非素数で割り切れる場合、それもまた割り切れる素数<=その除数があります。これにより、primes_in_range/total_rangeの係数で計算が削減されます。

28
ProdigySim

jequalsqrt(i)の場合、smallerである場合だけでなく、有効な要因である可能性もあります。

内部ループでsqrt(i)まで繰り返し処理するには、次のように記述できます。

_for (int j=2; j*j<=i; j++)
_

sqrt(i)を使用する場合と比較すると、これには浮動小数点数への変換が不要という利点があります。)

16
sth

数値に除数がある場合、そのうちの少なくとも1つは数値の平方根以下でなければなりません。除数をチェックするときは、テストする数までではなく、平方根までチェックするだけで済みます。

12
Jerry Coffin

これは、2〜100の素数をリストするための私の非常に単純なc ++プログラムです。

for(int j=2;j<=100;++j)
{
    int i=2;
    for(;i<=j-1;i++)
    {
        if(j%i == 0)
            break;
    }

    if(i==j && i != 2)
        cout<<j<<endl;
}
8
Carthi

実際、より良い解決策は、「素数を見つけるためのアルゴリズムの高速タイプである」「素数ふるいまたは素数ふるい」を使用することです。

単純な(ただし高速ではない)アルゴリズムは「serof eratosthenes」と呼ばれ、次の手順で実行できます(Wikipediaから):

  1. 2からnまでの連続した整数のリストを作成します:(2、3、4、...、n)。
  2. 最初に、pを2(最初の素数)に等しくします。
  3. Pから始めて、pの増分でカウントアップし、これらの各数値をリスト内のp自体より大きくマークします。これらの番号は2p、3p、4pなどです。それらのいくつかは既にマークされている可能性があることに注意してください。
  4. リスト内でマークされていないpより大きい最初の番号を見つけます。そのような番号がなかった場合、停止します。そうでない場合は、pをこの数(次の素数)に等しくし、手順3から繰り返します。
4

Ser of Eratosthenes logicを使用すると、はるかに高速な速度で同じ結果を達成できます。

マイコードデモ VS 受け入れられた回答

countを比較すると、私のコードはジョブを完了するまでの反復回数が大幅に少なくなります。最後に、さまざまなN値の結果をチェックアウトします。

このコードがすでに受け入れられているものよりも優れている理由:

-プロセス全体で偶数は一度もチェックされません。

-内側と外側の両方のループは、可能な制限内でのみチェックしています。余分なチェックはありません。

コード:

int N = 1000; //Print primes number from 1 to N
vector<bool> primes(N, true);
for(int i = 3; i*i < N; i += 2){    //Jump of 2
    for(int j = 3; j*i < N; j+=2){  //Again, jump of 2
        primes[j*i] = false;
    }
}
if(N >= 2) cout << "2 ";
for(int i = 3; i < N; i+=2){        //Again, jump of 2
    if(primes[i] == true) cout << i << " "; 
}

ために N = 1000、私のコードには1166回の反復が、受け入れられた答えには5287の時間がかかります(4.5倍遅い)

ために N = 10000、私のコードは14637回の反復を要し、受け入れられた回答は117526を要します(8倍遅い)

ために N = 100000、私のコードは175491回の反復を要し、受け入れられた回答は2745693(15.6倍遅い)を要します

4
Saurav Sahu

100までの素数を見つけることは特に素晴らしく簡単です:

    printf("2 3 ");                        // first two primes are 2 and 3
    int m5 = 25, m7 = 49, i = 5, d = 4;
    for( ; i < 25; i += (d=6-d) )
    {
        printf("%d ", i);                  // all 6-coprimes below 5*5 are prime
    }
    for( ; i < 49; i += (d=6-d) )
    {
        if( i != m5) printf("%d ", i);
        if( m5 <= i ) m5 += 10;            // no multiples of 5 below 7*7 allowed!
    }
    for( ; i < 100; i += (d=6-d) )         // from 49 to 100,
    {
        if( i != m5 && i != m7) printf("%d ", i);
        if( m5 <= i ) m5 += 10;            //   sieve by multiples of 5,
        if( m7 <= i ) m7 += 14;            //                       and 7, too
    }

100の平方根は10なので、このレンディションは- エラトステネスのふるい2-3ホイール は上記の素数の倍数を使用します310より大きくない-viz。 5および7のみ! -6-coprimes100を段階的にふるいにかける。

3
Will Ness

Forループをfor (int j=2; j<=sqrt(i); j++)に変更するのは問題ありませんが、それから何か他のものを変更する必要もあります。印刷条件を具体的に見ると、

_else if (i == j+1) {
      cout << i << " ";
}
_

sqrt(i)まで反復するだけで、なぜトリガーされないのですか?これを変更するためにcoutをどこに移動できますか? (ヒント:印刷をループ外に移動してから、何らかのタイプのフラグ変数を使用することもできます)

2
Jesse Cohen

次のコードで数値が素数であるかどうかを確認します(もちろんsqrtを使用):

bool IsPrime(const unsigned int x)
{
  const unsigned int TOP
  = static_cast<int>(
      std::sqrt( static_cast<double>( x ) )
    ) + 1;

  for ( int i=2; i != TOP; ++i )
  {
    if (x % i == 0) return false;
  }
  return true;
}

このメソッドを使用して素数を決定します。

#include <iostream>

using std::cout;
using std::cin;
using std::endl;

#include <cmath>

void initialize( unsigned int *, const unsigned int );
void show_list( const unsigned int *, const unsigned int );
void criba( unsigned int *, const unsigned int );
void setItem ( unsigned int *, const unsigned int, const unsigned int );

bool IsPrime(const unsigned int x)
{
  const unsigned int TOP
  = static_cast<int>(
      std::sqrt( static_cast<double>( x ) )
    ) + 1;

  for ( int i=2; i != TOP; ++i )
  {
    if (x % i == 0) return false;
  }
  return true;
}

int main()
{

    unsigned int *l;
    unsigned int n;

    cout << "Ingrese tope de criba" << endl;
    cin >> n;

    l = new unsigned int[n];

    initialize( l, n );

    cout << "Esta es la lista" << endl;
    show_list( l, n );

    criba( l, n );  

    cout << "Estos son los primos" << endl;
    show_list( l, n );
}

void initialize( unsigned int *l, const unsigned int n)
{
    for( int i = 0; i < n - 1; i++ )
        *( l + i ) = i + 2;
}

void show_list( const unsigned int *l, const unsigned int n)
{
    for( int i = 0; i < n - 1; i++ )
    {
        if( *( l + i ) != 0)
            cout << l[i] << " - ";
    }
    cout << endl;
}

void setItem( unsigned int *l, const unsigned int n, const unsigned int p)
{
    unsigned int i = 2;
    while( p * i <= n)
    {
        *( l + (i * p - 2) ) = 0;
        i++;
    }
}

void criba( unsigned int *l, const unsigned int n)
{
    for( int i = 0;  i * i <= n ; i++ )
     if( IsPrime ( *( l + i) ) )
        setItem( l, n, *(l + i) );      
}
2
fpointbin

これは、指定された数nまでのすべての素数を印刷するための簡単なコードです。

#include<iostream.h>
#include<conio.h>

void main()
{
clrscr();
int n,i,j,k;
cout<<"Enter n\n";
cin>>n;

for(i=1;i<=n;i++)
{   k=0;
  for(j=1;j<=i;j++)
  {
    if((i%j)==0)
    k++;
   }
  if(k==2)
  cout<<i<<endl;
}
getch();
}
0
palslav

私は常にこれを使用します(簡単で高速です):

#include <iostream>
using namespace std;

int i,j;
bool b[101];

int main( )
{
    for(i=2;i<101;i++){
        b[i]=true;
    }
    for(i=1;i<101;i++){
        if(b[i]){
            cout<<i<<" ";
            for(j=i*2;j<101;j+=i) b[j]=false;
        }
    }
}

このコードの出力は次のとおりです。2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

0
user3178413

この本は、Gary Bronsonが書いた「エンジニアと科学者向けのC++」(グーグルで検索)のようです。
これは可能な答えですか?私見それは驚くべきことです。

質問を(本から)数回読む必要がありました。私の解釈:
Foreachnumber N:2 <= N <100素数かどうかを確認します。
どうやって? Foreach除数D:2 <= D <sqrt(N)、
DがNを除算する場合、Nは素数ではありません。D> sqrt(N)の場合、Nは素数です。

試してみてください:

N = 2, sqrt(2) ≈ 1.41, D = 2, 2 < 1.41 ?  no 2 > 1.41 ? yes 2 is prime.  
N = 3, sqrt(3) ≈ 1.73, D = 2, 2 < 1.73 ?  no 2 > 1.73 ? yes 3 is prime.  
N = 4, sqrt(4) = 2.00, D = 2, 2 < 2.00 ?  no 2 > 2.00 ?  no 4 is not prime.  
N = 5, sqrt(5) ≈ 2.24, D = 2, 2 < 2.24 ? yes 5 % 2 > 0? yes  
                       D = 3, 3 < 2.24 ?  no 3 > 2.24 ? yes 5 is prime.    
N = 6, sqrt(6) ≈ 2.45, D = 2, 2 < 2.45 ? yes 6 % 2 = 0  2 > 2.45 ? no 6 is not prime.

私が見る限り、それは素数を見つける方法です、
ふるいを使わずに(ずっと、ずっと速く)、
ただし:答えは質問にあります!驚くべき?

速度? Primes <400,000:10秒未満(私の時計、ロレックスで、私は市場でそれを買いました、売り手はそれが本物で、2本のバゲットの価格で本物のもので、12本の本物のダイヤモンドもありました)。
素数を数えてみましょう(コードは表示しません;):664579素数<10,000,000:5秒。

#include "stdafx.h"
#include <math.h>
#include <iostream>
using namespace std;
int main()
{
    double rt;
    for (int d = 2, n = 2; n < 100; d = 2, n++)
    {
        for (rt = sqrt(n); d < rt; d++)
            if (n % d == 0) break;
        if (d > rt) cout << n << " ";
    }
    getchar();  // 25 primes :-)
}

(他の回答と同様に)プライムシーブのある以前の回答を削除しました。
次の「ネクロマンサー」バッジがもうすぐ届きますように。

著者に次のように尋ねました。あなたの本では、「C++ for E&S」は素数に関する演習です。[xrcs] ... [/ xrcs]。 7年前、SO/q/5200879で質問されました。
数日前に答えました:SO/a/49199435
それは合理的な解決策、またはおそらく解決策だと思いますか。

彼は答えました:ピーター、私が演習を構成しているとき、私は本当に具体的な解決策を心に抱いていません。
したがって、正確な解決策を考えていたとは言えません。 C++の喜びは、本当に創造的なソリューションと優れたコードを思いつくことができるということです。
送信していただきありがとうございます!
博士。ブロンソン

https://youtu.be/1175axY2Vvw に行きました

PS。ふるい: https://Pastebin.com/JMdTxbeJ

0
P_P

いいえかどうかを確認します。素数かC++でないか:

#include<iostream>
#include<cmath>

using namespace std;
int main(){

int n, counter=0;

cout <<"Enter a number to check whether it is prime or not \n";
cin>>n;

  for(int i=2; i<=n-1;i++) {
    if (n%i==0) {
      cout<<n<<" is NOT a prime number \n";
      break;
    }
    counter++;
                }
    //cout<<"Value n is "<<n<<endl;
    //cout << "number of times counter run is "<<counter << endl;
    if (counter == n-2)
      cout << n<< " is prime \n";
   return 0;
}
0
Sdembla

「N」個の素数を出力する簡単なプログラム。 N値を100として使用できます。

    #include  <iostream >
    using  namespace  std;

    int  main()
    {
        int  N;
        cin  >>  N;
        for (int  i =  2;  N > 0;  ++i)
        {
            bool  isPrime  =  true ;
            for (int  j =  2;  j < i;  ++j)
            {
                if (i  % j ==  0)
                {
                    isPrime  =  false ;
                    break ;
                }
            }
            if (isPrime)
            {
                --N;
                cout  <<  i  <<  "\n";
            }
        }
        return  0;
    }
#include<iostream>
using namespace std;
void main()
{
        int num,i,j,prime;
    cout<<"Enter the upper limit :";
    cin>>num;
    cout<<"Prime numbers till "<<num<<" are :2, ";

    for(i=3;i<=num;i++)
    {
        prime=1;
        for(j=2;j<i;j++)
        {
            if(i%j==0)
            {
                prime=0;
                break;
            }
        }
        if(prime==1)
            cout<<i<<", ";
    }
}
0
Gaurav

これは簡単なブログからの私のアプローチです:

//Prime Numbers generation in C++
//Using for loops and conditional structures
#include <iostream>
using namespace std;

int main()
{
int a = 2;       //start from 2
long long int b = 1000;     //ends at 1000

for (int i = a; i <= b; i++)
{

 for (int j = 2; j <= i; j++)
 {
    if (!(i%j)&&(i!=j))    //Condition for not prime
        {
            break;
        }

    if (j==i)             //condition for Prime Numbers
        {
              cout << i << endl;

        }
 }
}
}

-詳細は次を参照してください: http://www.programmingtunes.com/generation-of-prime-numbers-c/#sthash.YoWHqYcm.dpuf

0
user2808359
#include "stdafx.h"
#include<iostream>
using namespace std;
void main()
{ int f =0;
 for(int i=2;i<=100;i++)
  {
   f=0;
   for(int j=2;j<=i/2;j++)
   { 
     if(i%j==0)
     { f=1;
       break;
     }
   }
 if (f==0)
  cout<<i<<" ";
}
 system("pause");
}
0
Mohsin

エラトステネスのふるいの実装は次のとおりです(2とnの間の素数用)

#include <iostream>

int main (){
int n=0;
std::cout << "n = ";
std::cin >> n;
std::cout << std::endl;

if (n==0 || n==1){
    std::cout << "No primes in this range" << std::endl;
    return 0;
}


const int array_len = n-2+1;

int the_int_array[array_len];
for (int counter=2; counter <=n; counter++)
    the_int_array[counter-2]=counter;


int runner = 0;
int new_runner = 0;

while (runner < array_len ){
    if (the_int_array[runner]!=0){
        new_runner = runner;
        new_runner = new_runner + the_int_array[runner];

        while (new_runner < array_len){
           the_int_array[new_runner] = 0;
           new_runner = (new_runner + the_int_array[runner]);
        }
    }
runner++;
}

runner = 0;

while (runner < array_len ){
    if (the_int_array[runner]!=0)
        std::cout << the_int_array[runner] << " ";
    runner++;
}

std::cout << std::endl;
return 0;

}

0
pravish

分割可能性の素数のルールを使用すると、O(n)で見つけることができ、それは本当に効率的です Rules of Divisibility

解決策は、数字の個々の数字に基づいています...

0
NirmalGeo

ProdigySimの2番目の方法による最も人気のある回答に基づいて、Perlでそれを行いました。素数を2回出力するのを避けるために、print $i . " \n";の直後にPerlでbreakに相当するlastを追加する必要がありました。

#!/bin/Perl
use strict;

for(my $i=2; $i < 100; $i++){

    my $prime = 1;

    for (my $j=2; $j*$j<=$i; $j++){
        if ($i % $j == 0){
            $prime = 0;
            last;
        }
        if($prime) {
            print $i . " \n";
            last;
        }
    }

}
0
CoffeeAtBedtime