Ce code c ++ imprime les nombres premiers suivants: 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97.
Mais je ne pense pas que ce soit la façon dont mon livre veut qu'il soit écrit. Il mentionne quelque chose à propos de la racine carrée d'un nombre. J'ai donc essayé de changer ma 2ème boucle en for (int j=2; j<sqrt(i); j++)
mais cela ne m'a pas donné le résultat dont j'avais besoin.
Comment aurais-je besoin de changer ce code pour que mon livre le veuille?
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;
}
Un nombre entier premier est celui qui a exactement deux diviseurs différents, à savoir 1 et le nombre lui-même. Écrire, exécuter et tester un programme C++ qui trouve et affiche tous les nombres premiers moins que 100. (Indice: 1 est un nombre premier . Pour chaque nombre compris entre 2 et 100, find Reste = Nombre% n, où n compris entre 2 et sqrt (nombre). n .__ est supérieur à sqrt (nombre), le nombre n'est pas également divisible par n. Pourquoi? Si un reste est égal à 0, le nombre n'est pas un nombre premier.)
Trois façons:
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;
}
Edit: Dans le troisième exemple, nous gardons une trace de tous nos nombres premiers calculés précédemment. Si un nombre est divisible par un nombre non premier, il existe également un nombre premier <= ce diviseur par lequel il est également divisible. Cela réduit le calcul d'un facteur de prime_in_range/total_range.
Si j
est égal à à sqrt(i)
, cela pourrait également être un facteur valide, pas seulement si c'est plus petit .
Pour parcourir jusqu'à sqrt(i)
inclus dans votre boucle interne, vous pouvez écrire:
for (int j=2; j*j<=i; j++)
(Par rapport à l'utilisation de sqrt(i)
, ceci présente l'avantage de ne pas nécessiter de conversion en nombres à virgule flottante.)
Si un nombre a des diviseurs, au moins l'un d'entre eux doit être inférieur ou égal à la racine carrée du nombre. Lorsque vous vérifiez les diviseurs, il vous suffit de vérifier jusqu'à la racine carrée, pas jusqu'au nombre testé.
Ceci est mon programme très simple c ++ pour lister les nombres premiers entre 2 et 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;
}
en fait, la meilleure solution consiste à utiliser "un tamis principal ou un tamis de nombres premiers" qui "est un type d'algorithme rapide permettant de rechercher des nombres premiers".
L'algorithme simple (mais pas plus rapide) s'appelle "tamis d'eratosthenes" et peut être réalisé comme suit (à partir de wikipedia à nouveau):
- Créez une liste d'entiers consécutifs de 2 à n: (2, 3, 4, ..., n).
- Initialement, p = 2, le premier nombre premier.
- À partir de p, comptez par incréments de p et marquez chacun de ces nombres plus grand que p lui-même dans la liste. Ces chiffres seront 2p, 3p, 4p, etc .; notez que certains d'entre eux ont peut-être déjà été marqués.
- Recherchez le premier nombre supérieur à p dans la liste qui n'est pas marqué. S'il n'y en avait pas, arrêtez-vous. Sinon, laissez p maintenant égal à ce nombre (qui est le prochain nombre premier), et répétez à partir de l'étape 3.
En utilisant Sieve of Eratosthenes logic, je suis capable d’obtenir les mêmes résultats avec une vitesse beaucoup plus rapide.
Ma démo de code VS réponse acceptée .
En comparant la count
, Mon code prend beaucoup moins de temps pour terminer le travail. Consultez les résultats pour différentes valeurs N
à la fin.
Pourquoi ce code fonctionne mieux que ceux déjà acceptés:
- - les nombres pairs ne sont pas vérifiés, même une fois tout au long du processus.
- les boucles internes et externes ne vérifient que dans les limites possibles. Pas de vérifications superflues.
Code:
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 << " ";
}
Pour N = 1000
, mon code prend 1166 itérations, la réponse acceptée prend 5287 (4,5 fois plus lente)
Pour N = 10000
, mon code prend 14637 itérations, la réponse acceptée prend 117526 (8 fois plus lente)
Pour N = 100000
, mon code prend 175491 itérations, la réponse acceptée prend 2745693 (15,6 fois plus lente)
Trouver des nombres premiers jusqu’à 100 est particulièrement agréable et facile:
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
}
La racine carrée de 100 est 10, et donc cette interprétation de le tamis d'Eratosthenes avec la roue 2-3 utilise les multiples de seulement les nombres premiers au-dessus de 3 qui ne sont pas supérieurs à 10 - à savoir. 5 et 7 seul! - tamiser les 6 régimes en dessous de 100 de manière incrémentielle.
C'est bien de changer votre boucle for en for (int j=2; j<=sqrt(i); j++)
mais vous devez aussi changer quelque chose d'autre. En regardant spécifiquement votre état d'impression,
else if (i == j+1) {
cout << i << " ";
}
pourquoi cela ne se déclenchera-t-il jamais si vous ne parcourez que sqrt(i)
? Où pouvez-vous déplacer la cout
pour changer cela? (Indice: vous voudrez peut-être déplacer l’impression en dehors de la boucle, puis utiliser un type de variable drapeau)
Je vérifie si un nombre est premier ou non avec le code suivant (bien sûr, en utilisant 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;
}
J'utilise cette méthode pour déterminer les nombres premiers:
#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) );
}
voici un code simple pour imprimer tous les nombres premiers jusqu'au nombre n indiqué,
#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();
}
J'utilise toujours celui-ci (c'est facile et rapide):
#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;
}
}
}
Voici la sortie de ce code:
Le livre semble être "C++ pour ingénieurs et scientifiques" Écrit par Gary Bronson (googlé).
Est-ce une réponse possible? IMHO c'est surprenant.
J'ai dû lire la question (du livre) à quelques reprises. Mon interprétation:
Pour chaque nombre N: 2 <= N <100, vérifiez s'il est premier.
Comment? Pour chaque diviseur D: 2 <= D <sqrt (N),
si D divise N, N n'est pas premier, si D> sqrt (N), N est premier.
Essaie:
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.
Pour autant que je sache, c'est comme ça que les nombres premiers devraient être trouvés,
pas avec une passoire (beaucoup, beaucoup plus vite),
mais avec: la réponse est dans la question! Surprenant?
La vitesse? nombres premiers <400 000: moins de 10 secondes (sur ma montre, un Rolex, je l’ai acheté sur le marché, le vendeur a dit que c’était un vrai, un vrai pour le prix de deux baguettes, avec aussi 12 vrais diamants).
Comptons les nombres premiers (je ne vais pas montrer le code;): 664579 nombres premiers <100 000: 5 secondes.
#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 :-)
}
Supprimé une réponse précédente avec (comme d'autres réponses) un tamis primaire.
J'espère que j'aurai bientôt mon prochain badge "Nécromancien".
J'ai demandé à l'auteur: Dans votre livre: "C++ pour E & S" Est un exercice sur les nombres premiers, [xrcs] ... [/ xrcs] . Il y a sept ans, il était demandé à: SO/q/5200879
Il y a quelques jours, j'ai donné une réponse: SO/a/49199435
Pensez-vous que c'est une solution raisonnable, ou peut-être la solution?.
Il a répondu: Peter, je n'ai jamais vraiment de solution spécifique à l'esprit Quand je compose les exercices,
Je ne peux donc pas dire que j’avais votre solution exacte à l’esprit . La joie du C++ est que l’on peut trouver des solutions vraiment créatives et un excellent code, car, à première vue, il semble que Vous avez fait.
Merci de nous l'avoir envoyé!
Dr. Bronson
Je suis allé à https://youtu.be/1175axY2Vvw
PS. Un tamis: https://Pastebin.com/JMdTxbeJ
Pour savoir si non. est premier ou pas 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;
}
Un programme simple pour imprimer "N" nombres premiers. Vous pouvez utiliser la valeur N en tant que 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<<", ";
}
}
voici mon approche d'un simple blog:
//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;
}
}
}
}
- Voir plus sur: http://www.programmingtunes.com/generation-of-prime-numbers-c/#sthash.YoWHqYcm.dpuf
#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");
}
Voici mon implémentation de Sieve of Eratosthenes (pour les nombres premiers entre 2 et 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;
}
En utilisant les règles de divisibilité, les nombres premiers se trouvent dans O(n) et c’est vraiment efficace Rules of Divisibility
La solution serait basée sur les chiffres individuels du numéro ...
Je l'ai fait en Perl d'après la réponse la plus populaire fournie par la deuxième méthode de ProdigySim. J'ai dû ajouter un équivalent break
en Perl, last
, juste après le print $i . " \n";
pour éviter de générer deux fois les nombres premiers.
#!/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;
}
}
}