打印从1到100的素数

时间:2011-03-05 00:57:21

标签: c++ c algorithm primes

此c ++代码打印出以下素数: 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97。

但我不认为这就是我的书要写的方式。它提到了一些关于数字的平方根的东西。所以我尝试将我的第二个循环更改为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;
}
  

素数是具有的整数   正是两个不同的除数,   即1和数字本身。写,   运行,并测试一个C ++程序   查找并打印所有素数   小于100.(提示:1是素数   数。对于每个2到100的数字,   find Remainder = Number%n,其中n   范围从2到sqrt(数字)。如果是   大于sqrt(数字),   数字不能被n整除。   为什么?如果任何剩余等于0,则   数字不是素数。)

22 个答案:

答案 0 :(得分:28)

三种方式:

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;
}

编辑:在第三个例子中,我们跟踪所有先前计算的素数。如果一个数字可以被非素数除尽,那么还有一些素数&lt; =该除数,它也可以被除数。这会使计算减少一个primes_in_range / total_range。

答案 1 :(得分:16)

如果j 等于sqrt(i),它可能也是一个有效因素,不仅仅是更小

要在内循环中迭代并包含sqrt(i),您可以写:

for (int j=2; j*j<=i; j++)

(与使用sqrt(i)相比,这有利于不需要转换为浮点数。)

答案 2 :(得分:12)

如果数字有除数,则其中至少有一个必须小于或等于数字的平方根。当你检查除数时,你只需要检查平方根,而不是一直到被测试的数字。

答案 3 :(得分:8)

这是我非常简单的c ++程序,用于列出2到100之间的素数。

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;
}

答案 4 :(得分:4)

实际上更好的解决方案是使用“主筛或素数筛”,“这是一种快速找到素数的算法”..维基百科

简单(但不是更快)的算法被称为“eratosthenes筛”,可以通过以下步骤完成(再次来自维基百科):

  
      
  1. 创建从2到n的连续整数列表:(2,3,4,...,n)。
  2.   
  3. 最初,让p等于2,即第一个素数。
  4.   
  5. 从p开始,以p为增量进行计数,并在列表中将每个数字标记为大于p本身。这些数字将是   2p,3p,4p等;请注意,其中一些可能已被标记。
  6.   
  7. 在列表中找到未标记的第一个大于p的数字。如果没有这样的号码,请停止。否则,让p现在相等   这个数字(这是下一个素数),并从第3步重复。
  8.   

答案 5 :(得分:4)

使用Sieve of Eratosthenes逻辑,我能够以更快的速度获得相同的结果。

My code demo VS accepted answer

比较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次)

答案 6 :(得分:3)

查找 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 ,因此the sieve of Eratosthenes2-3 wheel的再现使用了上面的素数的倍数 3 不超过 10 - 即。仅 5 7 ! - 以增量方式筛选 100 - 100 以下的 6

答案 7 :(得分:2)

将for循环更改为for (int j=2; j<=sqrt(i); j++)可以,但您还需要更改其他内容。专门查看您的打印条件,

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

如果只迭代sqrt(i),为什么永远不会触发?你在哪里可以移动cout来改变它? (提示:您可能希望将打印输出循环,然后使用某种类型的标志变量)

答案 8 :(得分:2)

使用以下代码检查数字是否为素数(当然使用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) );      
}

答案 9 :(得分:0)

虽然这是相对更高的生产级素数生成器,但仍可用于查找1到100之间的素数。该代码使用Miller-Rabin Primality Test来计算素数。由于它是概率方法,因此精度随着k值的增加而增加。虽然重点放在代码的可读性而非速度上,但在AWS r5.2xlarge实例上,素数的花费为3.791秒,直到1,000,000。

// C++ program to print all primes smaller than or equal to 
// n using Miller-Rabin Primality Test
// Reference: https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test
// It is not particularly to optimized 
// since focus is readability
// Compile: g++  -std=c++17 -o prime prime.c++ -ltbb 

#include <execution>
#include <iostream>
#include <math.h>
using namespace std; 

int power(unsigned long int x, unsigned long y, unsigned long p){
    int res = 1;
    x = x % p;
    while (y > 0) {
        if (y & 1)
            res = (res * x) % p;
        y = y >> 1;
        x = (x * x) % p;
    }
    return res;
}

bool millerTest(unsigned long d, unsigned long n) {
    unsigned long a = 2 + rand () % (n - 4);

    unsigned long x = power(a, d, n);

    if (x == 1  || x == n - 1)
        return true;

    while (d != n - 1){
        x = (x * x) % n;
        d *= 2;
        if (x == 1) return false;
        if (x == n - 1) return true;

    }
    return false;
}

bool isPrime(unsigned long n, int k) {
    if (n <= 1 || n == 4) return false;
    if (n <= 3) return true;

    unsigned long int d = n - 1;
    while (d % 2 == 0)
        d /= 2;
    for(int i = 0; i < k; i++){
        if (!millerTest(d, n))
            return false;
    }
    return true;
}




int main() 
{ 
    int n = 1000000;
    int k = 200; 
    vector<unsigned long> primeN(n);
    iota(primeN.begin(), primeN.end(), 1);

    vector<bool> isPrimeV(n);



    transform(execution::par,
        primeN.begin(), primeN.end(), 
        isPrimeV.begin(), 
        [k](unsigned long x) -> bool {
            return isPrime(x, k);
        });

    int count = accumulate(isPrimeV.begin(), isPrimeV.end(), 0, [](int d, bool v){
        if (v == true) return d += 1; else return d;
    });
    cout << count << endl;

    return 0; 
} 

答案 10 :(得分:0)

这本书似乎是&#34; C ++ for Engineers and Scientists&#34; 由Gary Bronson撰写(谷歌搜索) 这是一个可能的答案吗?恕我直言,这令人惊讶。

我必须读几遍问题(从书中)。 我的解释:
对于每个数字N:2&lt; = N&lt; 100检查它是否是素数 怎么样?对于每个除数D:2&lt; = D&lt; 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.

据我所知,那应该如何找到素数,
不用筛子(更快,更快),
但是:答案就在问题中!令人惊讶?

速度?素数&lt; 400,000:不到10秒(在我的手表上,劳力士,我在市场上买了它,卖家说这是一个真正的,一个真正的两个法式长棍面包的价格,还有12个真正的钻石)。 /> 让我们计算素数(我不会显示代码;): 664579 primes&lt; 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 :-)
}

删除了早期的答案(如其他答案)和筛子 希望我得到我的下一个&#34;死灵法师&#34;徽章很快。

我问作者:在你的书中:&#34; C ++ for E&amp; S&#34; 是关于素数的练习,[xrcs] ... [/ xrcs]。 七年前,它被问到:SO / q / 5200879
几天前我给出了答案:SO / a / 49199435
您认为这是一个合理的解决方案,还是解决方案。

他回答说:彼得,我从来没有真正考虑过具体的解决方案 当我在做练习时,
所以我不能说我有你的确切解决方案。 C ++的乐趣在于,人们可以提出真正有创意的解决方案和优秀的代码, 乍一看,看起来你已经完成了。
谢谢你送它!
布朗森博士

我去了https://youtu.be/1175axY2Vvw

PS。筛子:https://pastebin.com/JMdTxbeJ

答案 11 :(得分:0)

这是一个简单的代码,用于打印所有素数,直到给定数字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();
}

答案 12 :(得分:0)

一个简单的打印程序&#34; N&#34;质数。您可以将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;
    }

答案 13 :(得分:0)

我是基于ProdigySim的第二种方法最流行的答案在perl中做到的。我必须在break后面的perl last中添加print $i . " \n";个等效项,以避免两次输出素数。

#!/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;
        }
    }

}

答案 14 :(得分:0)

要查找是否。是或不是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;
}

答案 15 :(得分:0)

我总是使用这个(它很简单快速):

#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

答案 16 :(得分:0)

这是我从一个简单博客的方法:

//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

答案 17 :(得分:0)

#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");
}

答案 18 :(得分:0)

这是我对Eratosthenes筛选的实现(适用于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;

}

答案 19 :(得分: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<<", ";
    }
}

答案 20 :(得分:0)

使用可分性规则素数可以在O(n)中找到,它真的很有效Rules of Divisibility

解决方案将基于数字的各个数字...

答案 21 :(得分:-1)

试试吧。 没有任何额外的内置功能,它很容易。

#include <iostream>

int prime(int n,int r){

  for(int i=2;n<=r;i++){
    if(i==2 || i==3 || i==5 || i==7){
      std::cout<<i<<" ";
      n++;
    } else if(i%2==0 || i%3==0 || i%5==0 || i%7==0)
      continue;
    else {
      std::cout<<i<<" ";
      n++;
    }
  }

}

main(){

  prime(1,25);
}

2 3 5 7 的测试足以达到 120 ,所以 100 没问题。

100 下面有 25 素数,在 121 = 11 * 11 下面 30