Sei sulla pagina 1di 9

19/01/2011 Algoritmi per la generazione dei nume…

Algoritmi per la generazione dei numeri primi


Da Wikipedia, l'enciclopedia libera.

Qui di seguito sono presenti alcuni algoritmi per la generazione di numeri primi minori o uguali ad un numero
assegnato N.

Qui (http://en.wikibooks.org/wiki/Efficient_Prime_Number_Generating_Algorithms) è possibile trovare algoritmi


in Phython ottimizzati

Indice

1 Java
2 C/C++
2.1 Pascal
2.2 Crivello di Eratostene
3 C#

Java
Questo metodo scritto in linguaggio Java consente la stampa in output tutti i numeri primi inferiori al parametro
"limitazione".

Si basa su un ciclo che scorre tutti i numeri inferiori al parametro e valuta tramite un secondo metodo di nome
"primo" se ogni singolo numero è primo o meno.

…wikipedia.org/…/Algoritmi_per_la_g… 1/9
19/01/2011 Algoritmi per la generazione dei nume…
public void stampaNumeriPrimi (int max) {

// Verranno stampati tutti i numeri primi minori di max.

for (int num = 2; num < max; num++)


if (primo (num))
System.out.println (num);
}

/**
* Restituisce {@code true} se il numero specificato è primo,
* {@code false} altrimenti.

*/
protected boolean primo(int numero){

// Istanziamo una variabile di scorrimento


// Il numero piu' alto per cui ha senso dividere (se si parte da 2) e'
// la radice quadrata del numero che stiamo testando.
int posMax = (int)Math.ceil(Math.sqrt(numero + 1));

// Nota: la condizione include un <= e non un <,


// perché numero potrebbe essere un quadrato perfetto.
for(int divisore = 2; divisore <= posMax; divisore++)
if (numero % divisore == 0 && numero!=2) return false; // controlla che il nume

// numero non ha divisori.


return true;
}

C/C++
Di seguito un algoritmo per la stampa dei numeri primi consecutivi. Si basa sul controllo di ogni singolo numero
dispari maggiore di 2 finché non viene raggiunto un limite prestabilito da voi.

…wikipedia.org/…/Algoritmi_per_la_g… 2/9
19/01/2011 Algoritmi per la generazione dei nume…
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main();
bool Prime(unsigned int * n);

int main () {
unsigned int l;

printf("\n GENERATORE DI NUMERI PRIMI CONSECUTIVI\n\n");


printf("Inserisci numero limite (maggiore di 1): ");

do {
scanf("%d", &l);
} while (l <= 2); // Chiede un numero finché non viene inserito un valore magg

printf("\n-\n\nI numeri primi da 0 a %d sono:\n\n2", l);

for(unsigned int a = 3; a <= l; a += 2) { // Genera i numeri da controllare unicamente


if(Prime(&a)) printf("\n%d", a); // Se è primo viene stampato
}

printf("\n\n-\n\n");
system("PAUSE");

return 0;
}

bool Prime(unsigned int * n) {


for(unsigned int b = 2; b <= (unsigned int)(trunc(sqrt(*n))); b++)
if((*n) % b = 0) {
return false;
}
return true;
}

Una versione alternativa

…wikipedia.org/…/Algoritmi_per_la_g… 3/9
19/01/2011 Algoritmi per la generazione dei nume…
#include <iostream>
#include <cmath>
using namespace std;

void numeri_primi(int max)


{
int k=(int)(max/trunc(log(max))); /* usa la stima di Gauss sul numero dei numeri prim
int i, j , pasI=2;
int *dp=new int[k];
int *m=new int[k];
int massimo=1,prova;

dp[0]=5;
m[0]=25;

if (max >=2){
cout<<2<<endl;
}
if (max >=3){
cout<<3<<endl;
}
if (max >=5){
cout<<5<<endl;
}

for(i=7; i<max ;i+=(pasI=6-pasI)) // evita i multipli di 3


{
/* cerca i divisori tra i primi già trovati fino a sqrt(i) */
for(prova = dp[j=0]; (i%m[j]) && prova*prova < i; prova=dp[++j])
{
if(i>m[j])
m[j]+= 2*prova;
}
if(i!=m[j])
{
cout<<i<<endl;
dp[massimo]=i;
m[massimo++]=i*i;
}
}

delete dp;
delete m;
}

int main(void)
{
int i;

cout<<"Introdurre il numero Max : "<<endl;


cin>>i;
numeri_primi(i);
}

Una versione semplice e veloce che permette la ricerca dei primi N (numero inserito dall'utente) numeri primi

…wikipedia.org/…/Algoritmi_per_la_g… 4/9
19/01/2011 Algoritmi per la generazione dei nume…
#include <iostream>
using namespace std;

bool verifica_Primo (const int Num_da_controllare)


{
for (int k = 3; k < Num_da_controllare; k++)
if (Num_da_controllare%k == 0) // se k è un divisore del numero in esame, la funzion
return false;
return true; /* se durante il ciclo for la funzione non è stata settata a false,
vuol dire che non sono stati trovati divisori, quindi il numero è pr
}

int main()
{
int N, riemp = 1, i = 3;

cout << "Quanti numeri primi vuoi trovare?\n";


cin >> N;

cout << "\nI primi " << N << " numeri primi sono:\n2\n";
do
{
if (verifica_Primo(i))
{
cout << i << endl;
riemp++;
}

i+=2; /* si incrementa i di due, anziché di uno perché non ha senso passare da un


(visto che per definizione hanno sempre almeno il 2 come divisore) */

} while (riemp < N);

system ("pause");
return 0;
}

Con la stessa logica un altro algoritmo per la generazione di numeri primi, questa volta inferiori ad un numero N
inserito dall'utente

…wikipedia.org/…/Algoritmi_per_la_g… 5/9
19/01/2011 Algoritmi per la generazione dei nume…
#include <iostream>
using namespace std;

bool verifica_Primo (const int Num_da_controllare)


{
for (int k = 3; k < Num_da_controllare; k++)
if (Num_da_controllare%k == 0) // se k è un divisore del numero in esame, la funzion
return false;
return true; /* se durante il ciclo for la funzione non è stata settata a false,
vuol dire che non sono stati trovati divisori, quindi il numero è pr
}

int main()
{
int N, i = 3;

cout << "Qual e' il numero limite?\n";


cin >> N;

cout << "\nI numeri primi minori di " << N << " sono:\n2\n";
while (i <= N)
{
if (verifica_Primo(i))
cout << i << endl;

i+=2; /* si incrementa i di due, anziché di uno perché non ha senso passare da un


(visto che per definizione hanno sempre almeno il 2 come divisore) */

};

system ("pause");
return 0;
}

Pascal

…wikipedia.org/…/Algoritmi_per_la_g… 6/9
19/01/2011 Algoritmi per la generazione dei nume…
program numeri_primi;
uses crt;
var
a,b:longint;
c:real;
begin
clrscr;
write('Dammi il numero da verificare : '); readln(a);
b:=a;
c:=1 + sqrt(a);
a:=round(c);
if a=1 then writeln('1 non è primo')
else if a=2 then writeln('2 è primo!')
else if a=0 then writeln('Con tanti numeri che ci sono proprio 0 dovevi s
else
begin
repeat
begin
a:= a -1;
end;
until (a=2) or (b mod a = 0);

if b mod a = 0 then
begin
a:=b;
writeln(b,' non è primo!');
writeln('I suoi divisori sono: ');
for a:= b-1 downto 2 do
if b mod a = 0 then write(' ',a,' ');
writeln(' ');
end
else if a=2 then writeln(b,' è primo!')
else writeln('ERRORE!');
end
end.

Crivello di Eratostene
Un numero intero N non può avere tutti i divisori maggiori della sua radice quadrata. Per verificare se un numero
è primo basta quindi dividerlo per gli interi e calcolare il resto. Se il resto è sempre diverso da
zero, allora il numero è primo. Per evitare estrazioni di radice allarghiamo la ricerca tra 2 e N/2 in quanto per N
>= 2, vale .

…wikipedia.org/…/Algoritmi_per_la_g… 7/9
19/01/2011 Algoritmi per la generazione dei nume…
#include <stdio.h>
#include <stdlib.h>
FILE *pfile;
/*prototipi funzioni*/
void creafile(void);
void crivello_eratostene(long int pvett[], long int *pn);

int main()
{
long int N, *pvett;

printf("Software che calcola i numeri primi usando:\nCRIVELLO DI ERATOSTENE\n\n


printf("Inserire N:\n");
scanf("%ld", &N);
if((pvett= malloc(N*sizeof(long int))) == NULL)
printf("Insufficient memory!\n\n");
else
{
creafile();
crivello_eratostene(pvett, &N);
fclose(pfile);
printf("esecuzione terminata con successo!\n\nFile creato\n\n");
free(pvett); /*distruzione dell'array*/
}

exit(EXIT_SUCCESS);
return 0;
}
/*funzione che crea il file dove salvare i numeri primi*/
void creafile(void)
{
char nomefile[20];

printf("Nome da dare al file sul quale salvare i dati:\n");


scanf("%s", nomefile);
if((pfile= fopen(nomefile, "w")) == NULL)
{
printf("Errore creazione file!\n\n");
exit(EXIT_FAILURE);
}

return;
}
/*funzione che calcola i numeri primi*/
void crivello_eratostene(long int pvett[], long int *pn)
{
long int i, j;

for(i=2; i< (*pn); i++) pvett[i]= 1;


for(j=2; j< (*pn); j++)
for(j=2; (i*j)< (*pn); j++) pvett[i*j]= 0;
/*stampo su file*/
for(i=2; i< (*pn); i++)
if(pvett[i])
fprintf(pfile,"%ld\n", i);
return;
}

C#
Questo metodo scritto in linguaggio C# consente la stampa in output tutti i numeri primi inferiori al parametro
"limite".
…wikipedia.org/…/Algoritmi_per_la_g… 8/9
19/01/2011 Algoritmi per la generazione dei nume…
Si basa su un ciclo che scorre tutti i numeri inferiori al parametro e valuta tramite un secondo metodo di nome
"primo" se ogni singolo numero è primo o meno.
using System;

namespace Numeri_Primi
{
class Program
{
static void Main(string[] args)
{
int limite;
Console.WriteLine("Scrivi Limite:");
limite = Convert.ToInt32(Console.ReadLine());
if (limite > 1)
{
int pos = 2;
while (pos <= limite)
{
if (primo(pos)) Console.WriteLine(pos);
pos++;
}
}
Console.Read();
}

static protected bool primo(int numero)


{
int pos = (numero + 1) / 2;
while (pos > 1)
{
if (numero % pos == 0 && pos != numero && pos != 1) return false;
pos--;
}
return true;
}
}
}
Categorie: Algoritmi numerici | Teoria dei numeri | [altre]

Ultima modifica per la pagina: 14:28, 16 gen 2011.


Il testo è disponibile secondo la licenza Creative Commons Attribuzione-Condividi allo stesso modo;
possono applicarsi condizioni ulteriori. Vedi le condizioni d'uso per i dettagli. Wikipedia® è un marchio
registrato della Wikimedia Foundation, Inc.

Politica sulla privacy


Informazioni su Wikipedia
Avvertenze

…wikipedia.org/…/Algoritmi_per_la_g… 9/9