Sunteți pe pagina 1din 6

ALGORITMI SPECIFICI NUMERELOR PRIME

Formularea temei. Să se scrie funcţii pentru afişarea divizorilor şi a descompunerii


în factori primi a unui număr natural.

Noţiuni teoretice. Prin număr prim se înţelege orice număr natural mai mare sau
egal cu 2 care are exact doi divizori. Cum orice număr natural are ca divizori pe 1 şi pe el
însuşi, se poate afirma că numerele prime sunt numerele naturale care au ca divizori numai
pe 1 şi pe el însuşi.
Conform definiţiei, numărul 2 este considerat număr prim, fiind singurul număr prim
par. Se poate demonstra că dacă un număr natural n nu are divizori în intervalul [2; n ] ,
atunci el este număr prim.
Pornind de la descompunerile în factori primi, pot fi evaluaţi c.m.m.d.c. a două
numere naturale, reţinând termenii comuni la puterea cea mai mare, respectiv c.m.m.m.c.,
format cu termenii comuni şi necomuni la puterea cea mai mică.
În practică, pentru calculul c.m.m.d.c. se utilizează algoritmul lui Euclid. Conform
acestuia, se împarte primul număr la al doilea, apoi împărţitorul şi restul de la pasul curent
devin deîmpărţit şi împărţitor pentru pasul următor. Procedeul se repetă pană la obţinerea
ultimului rest nenul, care este de fapt valoarea c.m.m.d.c.

Exerciţiul 1. Să se scrie o funcţie care să afişeze toţi divizorii unui număr natural
citit de la tastatură.

Propunere de algoritm. Divizorii unui număr natural a, cu excepţia numărului


însuşi, vor fi căutaţi în intervalul [1; a 2] . Parcurgerea acestuia se face în cadrul unei
instrucţiuni repetitive, verificându-se valoarea restului împărţirii întregi a argumentului la
numărul de la pasul respectiv. Valorile pentru care restul este nul sunt divizori şi vor fi
memorate, în scopul afişării, într-un vector. Variabila ce memorează indicii elementelor sale
se incrementează la fiecare apariţie a unui rest nul.
La lista divizorilor se adaugă, conform observaţiei de mai sus, valoarea numărului
însuşi. Situaţia numărului 0 se tratează separat, el acceptând ca divizor orice număr natural.

div( a) := "Orice numar este divizor al lui 0" if a 0


otherwise
k←0 1
div( 2) =  div( 1) = ( 1 )
a 2
for i ∈ 1 ..
2
1
if ¬mod( a , i) 2
v ←i
k
 
3
div( 12) =   div( 0) = "Orice numar este divizor al lui 0"
k←k+ 1 4
v ← a if a ≠ 1 6
k

v  12 
38 6. Algoritmi specifici numerelor prime

Funcţia MathCAD propusă are ca parametru formal numărul ai cărui divizori se


caută. Ea returnează, ca date de ieşire, fie un vector, v, ce conţine divizorii, fie un mesaj, în
cazul argumentului nul. Variabila locală, k, indexează elementele vectorului v iar cu
variabila de ciclare, i, se parcurge intervalul în care se caută divizorii. Pentru obţinerea
restului împărţirii întregi, în MathCAD, s-a utilizat funcţia predefinită mod.
Se dă în continuare o variantă de cod în limbaj C. Semnificaţia variabilelor este
aceeaşi. Memorarea divizorilor într-un vector, în scopul afişării, nu a mai fost necesară.

#include<stdio.h>
#include<conio.h>
main(){
int a,i;
printf(ʺIntroduceti numarul:ʺ);
scanf(ʺ%iʺ,&a);
if(!a)printf(ʺOrice numar este divizor al lui zeroʺ);
else
{printf(ʺDivizorii numarului %i sunt:\tʺ,a);
for(i=1;i<=a/2;i++)
if(!(a%i))printf(ʺ%i\tʺ,i);
printf(ʺ%iʺ,a);}
getch();}

Exerciţiul 2. Să se scrie o funcţie care să returneze descompunerea în factori primi a


unui număr natural.

Propunere de algoritm. Argumentul formal al funcţiei este numărul citit, a.


Divizorii primi se caută în intervalul [2, a] . Dacă variabila i reţine un divizor, valoarea
variabilei a este suprascrisă cu câtul împărţirii întregi a lui a la i. Variabila test, iniţializată
cu 0, îşi modifică valoarea când divizorul i încetează să mai fie divizor pentru noua valoare
a lui a. Se întrerupe astfel incrementarea variabilei putere, care memorează puterea
factorului prim respectiv. La găsirea unui nou divizor, variabila putere este adusă din nou la
valoarea 0.

fact_prim( a) := k←0
for i ∈ 2 .. a 2 2
fact_prim( 20) = 
putere ← 0
5 1
while ¬mod( a , i)
2 2
putere ← putere + 1 fact_prim( 36) = 
3 2
a
a←
i 2 2
if putere fact_prim( 700) =  5 2

m
k, 0
←i 7 1
m ← putere
k, 1
k←k+ 1
m
6. Algoritmi specifici numerelor prime 39

Funcţia fact_prim are ca dată de intrare numărul citit de la dispozitivul de intrare şi


returnează o matrice având pe prima coloană factorii primi iar pe a doua puterile aferente.
Un divizor este introdus în matrice numai după găsirea puterii la care el apare în dezvoltare.
O valoare nenulă a variabilei putere determină memorarea în matrice, pe linia k, a
divizorului (variabila i) şi a puterii sale (variabila putere). Valoarea lui k se incrementează la
găsirea unui nou divizor, determinând adăugarea unei linii noi în matrice.
Se propune în continuare un cod în limbaj C, păstrându-se algoritmul şi semnificaţia
variabilelor. În afişarea datelor de ieşire nu s-a mai utilizat matricea m, datorită
posibilităţilor de afişare ale acestui limbaj.

#include<stdio.h>
#include<conio.h>
main(){
int a,putere,i=2;
printf(ʺDati nr:ʺ);
scanf(ʺ%iʺ,&a);
while (i<=a)
{
putere=0;
while(!(a%i))
{a=a/i;
putere=putere+1;}
if(putere)
printf(ʺFactorul %i apare la puterea %i\nʺ,i,putere);
i++;
}
getch();}

Exerciţiul 3. Să se scrie o funcţie care să returneze valoarea 1 dacă argumentul ei,


număr natural, e prim şi 0 în caz contrar.

Propunere de algoritm. Conform unei teoreme cunoscute, dacă un număr nu


acceptă divizori mai mari ca 2 şi mai mici decât valoarea radicalului său, atunci el este prim.
Numărul natural 2 este considerat număr prim prin definiţie.
Propunerea de algoritm vizează utilizarea unei variabilă test, iniţializată cu 0, care îşi
modifică valoarea la găsirea primului divizor, determinând ieşirea din instrucţiunea
repetitivă şi afişarea rezultatului.

prim( a) := 1 if a 2
otherwise
test ← 0
for i ∈ 2 .. a prim( 9) = 0
test ← 1 if ¬mod( a , i) prim( 2) = 1
break if test
prim( 7) = 1
¬test
40 6. Algoritmi specifici numerelor prime

Conform cerinţei, funcţia prim are ca parametru de apelare numărul de testat şi


returnează 1 dacă acesta este prim şi 0 în caz contrar. Cazul argumentului 2 este tratat ca
excepţie, datorită particularităţii sale.
Se dă în continuare o variantă în limbaj C. Deoarece în instrucţiunea repetitivă For
variabila de ciclare nu se poate decât incrementa, este necesară tratarea excepţiilor 0 şi 1.

#include<stdio.h>
#include<conio.h>
#include<math.h>
main(){
int a,i,test=0;
printf(ʺDati nr:ʺ);scanf(ʺ%iʺ,&a);
if((a==0)||(a==1)) test=1;
for(i=2;i<=sqrt(a)&&(!test);i++)
if(!(a%i)) test=1;
printf(ʺ%iʺ,!test);
getch();}

Exerciţiul 4. Să se scrie o funcţie care să afişeze primele n numere prime, cu n citit


de la dispozitivul de intrare.

Propunere de algoritm. Printr-o instrucţiune repetitivă, de variabila de ciclare i, se


caută în numerele naturale pornind de la 0 pe cele prime. Pentru identificarea lor se poate
utiliza funcţia declarată la exerciţiul precedent. Valorile pentru care expresia prim(i) este
nenulă vor fi memorate într-un vector, în scopul afişării. Variabila k, ce memorează indicii
elementelor acestui vector, se incrementează la adăugarea unui nou element. Instrucţiunea
repetitivă se încheie când variabila k atinge valoarea citită în variabila n.

n_prime( n ) := k←0 2


i←0 3
 
while k < n 5
if prim( i) 7
n_prime( 8) =  
v ←i
k  11 
k←k+ 1  13 
 17 
i←i+ 1

v  19 

Funcţia n_prime admite ca parametru formal numărul de numere prime căutat. Ea le


memorează ca elemente ale unui vector, care este afişat ca dată de ieşire.

#include<stdio.h>
#include<conio.h>
#include<math.h>
main(){
int i=0,n,k=0,prim(int a);
printf(ʺCate numere doriti sa afisati?ʺ);
6. Algoritmi specifici numerelor prime 41

scanf(ʺ%iʺ,&n);
printf(ʺPrimele %i numere prime sunt:\tʺ,n);
while(k<n)
{if(prim(i))
{printf(ʺ%i\tʺ,i);
k++;}
i++;}
getch();}

int prim(int a){


int i,test=0;
if((a==0)||(a==1)) test=1;
for(i=2;i<=sqrt(a)&&(!test);i++)
if(!(a%i)) test=1;
return(!test);}

Exerciţiul 5. Să se scrie o funcţie care să returneze cel mai mare divizor comun a
două numere.

Propunere de algoritm. Conform algoritmului lui Euclid, valoarea celui mai mare
divizor comun este dată de ultimul rest nenul al împărţirilor succesive având ca deîmpărţit şi
împărţitor împărţitorul, respectiv restul de la pasul precedent.

cmmdc( a , b ) := while 1
rest ← mod( a , b )
break if ¬rest
a←b cmmdc( 52, 13) = 13
b ← rest cmmdc( 24, 60) = 12
b

Funcţia cmmdc admite ca parametri formali cele două numere şi returnează


valoarea celui mai mare divizor comun. Restul împărţirii întregi între numerele argument
este memorat în variabila rest. Dacă valoarea ei este nenulă, împărţitorul devine deîmpărţit
iar restul împărţitor, calculându-se noua valoare pentru rest. La anularea ei, se iese din ciclu,
afişându-se valoarea împărţitorului de la pasul curent, care este aceeaşi cu valoarea restului
de la pasul precedent.
Se dă în continuare o variantă de cod în limbaj C, păstrându-se semnificaţia
variabilelor:

#include<stdio.h>
#include<conio.h>
main(){
int a,b,rest;
printf(ʺIntroduceti numerele:ʺ);
scanf(ʺ%i%iʺ,&a,&b);
printf(ʺC.m.m.d.c. al numerelor %i si %i este ʺ,a,b);
42 6. Algoritmi specifici numerelor prime

while (1)
{rest=(a%b);
if(!rest)break;
a=b;
b=rest;}
printf(ʺ%iʺ,b);
getch();}

Exerciţiul 6. Să se scrie o funcţie care să returneze cel mai mic multiplu comun a
două numere.

Propunere de algoritm. Conform unei proprietăţi cunoscute, produsul dintre cel


mai mic multiplu comun şi cel mai mare divizor comun a două numere este egal cu
produsul acestora.

a⋅ b
cmmmc( a , b ) := cmmmc( 24, 60) = 120
cmmdc( a , b )
cmmmc( 52, 13) = 52

Se dă în continuare o variantă de cod în limbaj C:

#include<stdio.h>
#include<conio.h>
main(){
int a,b,cmmdc(int a,int b);
printf(ʺIntroduceti numerele:ʺ);
scanf(ʺ%i%iʺ,&a,&b);
printf(ʺC.m.m.m.c. al numerelor %i si %i este %iʺ,a,b,a*b/cmmdc(a,b));
getch();}

int cmmdc(int a,int b){


int rest;
while (1)
{rest=(a%b);
if(!rest)break;
a=b;
b=rest;}
return(b);}

Temă de lucru
1. Se citesc două numere naturale. Să se afişeze numerele prime cuprinse în intervalul
determinat de ele.
2. Să se afişeze numerele naturale mai mici decât un număr n dat care împărţite la 3
dau restul 2 şi împărţite la 5 dau restul 3.

S-ar putea să vă placă și