Algoritmiinformatik.ddbuftea.ro/lectii de probleme.pdf · 2019-11-12 · Subprograme • sunt...

Post on 06-Jan-2020

5 views 0 download

transcript

Algoritmi

1. Se citește un număr natural n. Să se calculeze : 𝑛!={1,𝑑𝑎𝑐ă 𝑛=0

1∗2∗3∗…∗𝑛,𝑑𝑎𝑐ă 𝑛≥1 } 2. Să se calculeze valoarea expresiei:

a. E=1*2 + 2*3 + 3*4 + ... + n*(n+1) b. E=1+2+3+...+n

c. E=1*2 - 2*3 + 3*4+...+(-1)n *n*(n+1) d. E=11+12+13+⋯+1𝑛e. E=11!+12!+13!+⋯+1𝑛!

3. Să se afișeze numerele mai mici sau egale cu n astfel: (1, n), (2,n-1), (3,n-2)...

*realizati percurgerea programului*transformati for in do si while

Probleme cu cifrele unui număr

Frecvent se pune problema prelucrării cifrelor unui număr și pentru realizareaacestuia se pune problema separării și analiza individuală a fiecărei cifre dintr-un număr dat.

int main(){ cout<<”N=”;

cin>>N;

while (N!=0){ .......N%10; //prelucreaza ultima cifra a lui N

N=N/10; //stergem ultima cifra}

Cout<<”afiseaza cerinta ”<<rezultat;}

• Se citeste un numar format din mai multe cifre.1. Sa se afiseze cifrele separate prin spatii .2. Sa se afiseze suma cifrelor numarului

Se citesc mai multe numere pana se tasteaza cifra 0. Sa se afiseze cifrele pare al numerelorcitite si suma lor

Sa se afiseze divizorii unui numar citit n

Se citesc n valori , sa se afiseze valoarea maxima

Se citesc mai multe valori pana se tasteaza 0.Sa se afiseze cifra valorilor pare, produsul cifrelor impare

Varianta 1citeste A,B;cat timp (B!=0) executa{R=A%B;A=B;B=R;}//se iese cand B este nul=>

scrie A;

Varianta 2.citeste A,Bcat timp (A!=B) executadaca (A>B)

atunci A=A-B;altfel B=B-A;scrie A;

Varianta 3.citeste A,B;cat timp (A*B!=0) executa //daca nici unul nu e nul….daca (A>B) atunci A=A%B;

altfel B=B%A;scrie A+B; //afisez valoarea nenula

Varianta 4.

citeste A, B;cmmdc=0;pentru D=1 , A executadaca (A%D==0 si B%D==0 )

atunci cmmdc=D;scrie cmmdc

CMMDC(a,b)

Problema. Fie doua numere naturale A si B. Sa se determine cel mai mare divizor comun a lui A si B.Sa citim iar: Practic trebuie sa determinam un numar natural care sa fie divizor atat pentru A cat si pentru B. Daca sunt mai multe numere in aceasta situatie, atunci il alegem pe cel mai mare.

.

Calculul CMMMCPentru calculul matematic a cmmdc pentru doua numere A si B, se realizeaza descompunereain factori primi si apoi se considera termenii comuni, la puterea cea mai mica.Pentru calculul matematic a cmmmc pentru doua numere A si B, se realizeaza descompunereain factori primi si apoi se considera termenii comuni si necomuni, la puterea cea mai mare.

A*B=CMMDC(A,B)*CMMMC(A,B).

Cmmdc=3 Cmmmc=18

a= 8

b=10𝑎

𝑏

#include <iostream>using namespace std;int main(){ int a,b,r;

cout << "a=" ; cin>>a;cout << "b=" ; cin>>b;

while(b!=0){ r=a%b;

a=b;b=r;

}cout<<"cmmdc="<<a;return 0;}

cmmmc * cmmdc =a*b;

#include <iostream>using namespace std;int main(){ int a,b,r;

cout << "a=" ; cin>>a;cout << "b=" ; cin>>b;

while (a!=b)if(a>b) a=a-b;else b=b-a;

cout <<"cmmdc= "<<a;

CEL MAI MARE DIVIZOR COMUN

ALGORITMUL LUI NICOMAHUS(metoda scaderilor repetate)

CEL MAI MIC MULTIPLU COMUN

ALGORITMUL LUI EUCLID(metoda impartirilor succesive)

Testarea unui numar prim

Afisarea numerelor prime pereche

pentru a nu pierde numarul n dupa divizari, il retinem in x

Initializam numarul reconstruit din cifre

Testarea unui numar palindrom

Ordinul de multiplicitate a divizorilor unui numar

Transformarea unui numar zecimal in numar binar

#include <iostream>#include<cmath>

using namespace std;

int main(){int n,a;

cout << "n=" << endl;cin>>n;a=sqrt(n);if(a==(sqrt(n)))cout<<"n patrat perfect";else cout<<"nu este pp";return 0;

}

#include <iostream>#include <fstream>using namespace std;int main(){ ifstream f("date.in");

ofstream g("date.out");int t[100],i,n, s;char cl[20];g<<"din ce clasa "; f>>cl;s=0;g<< "cati elevi sunt in clasa "; f>>n;for(i=1;i<=n;i++) //citirea vectorului{ g<<"\n elevul " <<i;

f>>t[i];}

for(i=1;i<=n;i++) // prelucrare vectors=s+t[i];

for(i=1;i<=n;i++) //afisare vectorg<<t[i]<<" ";

g<<"\n media elevilor din clasa "<<cl<< " este "<<s/n;f.close();g.close();return 0;}

Generarea unui vector cu rand

Numararea elementelor pare si impare

a[j]=aux;}//urmeaza afisarea sirului sortat cout<<"Sirul sortat crescator este:"<<=n;i++)cout<<a[i]<<" ";}

Adaugare element la capat

Adaugare element pe pozitia k

Se stiu doi vectori sortați a si b,

Prin interclasarea lor se înțelege construirea unui al treilea vector sortat c care să

conțină toate elementele acestora din a si b.

Se parcurg contorii i si j , se cauta valoarea minima si o duce in c

1

Contorul i parcurge de la 0n vectorul a

Contorul j parcurge de la 0 m vectorul b

Contorul p parcurgevectorul c

•Afisam vectorul c pentru p=0n+m

Declaram a[50], b[50], c[100], n, m, i, j, p;

Citeste a[i];Citeste b[j];int i = 0, j = 0;

while (i < n && j < m)if (a[i] < b[j])

{ c[p] = a[i]; p=p+1; i=i+1;}else

{ c[p++] = b[j++]; p=p+1; j=j+1;}

while (i < n)c[p++] = a[i++];

while (j < m)c[p++] = b[j++];

for(p=0; p<=n+m; p++)cout<<c[p]<<“ ”;

•Inserăm în c elementele rămase din a.

•Inserăm în c elementele rămase din b.

•Parcurgem simultan cei doi vectori,

cât timp i < n și j < m.

Dacă a[i] < b[j], atunci c[p] devine a[i], și îi incrementăm pe i++ și p++.

2

Fișiere text

Subprograme

• sunt părţi ale unui program (modularizate),

• se identifica prin nume,

• In functie de rezultatul returnat , functia va avea un tip de data (void, int, float)

• se pot activa la cerere prin intermediul acestor nume.

int Maxim (int p, int q){

if (p>q) return p;elsereturn q;}

int main(){ int max;max=Maxim(10,20);max=Maxim(max,30);}

Definiţia unui subprogram reprezintă de fapt descrierea unui proces de calcul cu ajutorul

variabilelor virtuale (parametri formali)

Apelul unui subprogram nu este altceva decât execuţia procesului de calcul pentru cazuri

concrete (cu ajutorul parametrilor reali, (efectivi, actuali) ).

tip_returnat nume_funcţie (lista parametrilor formali)

{

instrucţiune; // corpul funcţiei

return x;

}

Definiţia unei funcţii are forma generală:

Unde:

•tip_returnat: reprezintă tipul rezultatului calculat şi returnat de funcţie şi poate fi: int,

char, char*, long, float, void, etc.

•nume_funcţie: Contine doar literele mari si mici ale alfabetului englez, cifrele

sistemului zecimal, caracterul ’_’, cu conditia ca primul caracter sa nu fie cifra.

•lista parametrilor formali: reprezintă o listă de declaraţii de variabile separate prin

virgulă. Această listă poate să fie şi vidă. Pentru fiecare parametru format trebuie :

• tipul parametrului

• numele lui

• modul de transfer (valoare sau referinta)

nume_funcţie (lista parametrilor efectivi);

Apelul unei funcţii care nu returnează o valoare are urmatoarea

forma generala:

#include <iostream>

using namespace std;

void f1 ( )

{ cout << "abc";

}

int main ()

{ f1();

return 0;

}

/* Functia f1 este o functie cu rezultat

void, care nu are parametri formali.

In urma executiei programului se va

afisa: abc */

unde notiunea de parametru efectiv = parametru actual = parametru real = parametru de apel, iar lista parametrilor efectivi poate sa fie vidă, o expresie sau mai multe despărţite prin virgulă

#include <iostream>

using namespace std;

void f2(int k)

{ for (int i=1; i<=k ; i++)

cout << "abc"<< " ";

}

int main ()

{

f2 (3);

return 0;

}

/* Functia f2 este o functie cu rezultat

void, care are un singur parametru

formal K.

Functia f2 este apelata pentru valoarea

3, valoare care va fi preluata de

parametrul formal k si se va afisa:

abc abc abc */

• poate fi apelată ca operand al unei expresii,

• sau poate fi afisata valoarea returnata cout<<nume_functie

Apelul unei funcţii care returnează o valoare

La apelul unei funcţii, valorile parametrilor efectivi se atribuie

parametrilor formali corespunzători.

În momentul în care se întâlneşte un apel de funcţie,

controlul execuţiei programul este transferat primei

instrucţiuni din funcţie, urmând a se executa secvenţial

instrucţiunile funcţiei.

#include <iostream>using namespace std;int schimb(int x, int y){int z;z=x; x=y; y=z;}int main(){int a,b;cout<<"a= "; cin>>a;cout<<"b= "; cin>>b;schimb(a,b);cout<<a<<" "<<b;}

#include <iostream>using namespace std;

int schimb(int &x, int &y){int z;z=x; x=y; y=z;}

int main(){int a,b;cout<<"a= "; cin>>a;cout<<"b= "; cin>>b;schimb(a,b);cout<<a<<" "<<b;}

#include <iostream>using namespace std;

void schimba(int &x,int &y){int z;z=x; x=y; y=z;}int main(){int a,b,c;cout<<"a= "; cin>>a;cout<<"b= "; cin>>b;cout<<"c= "; cin>>c;if (a>b) schimba(a,b);if (b>c) schimba(b,c);if (a>b) schimba(a,b);if (b==(a+c)/2)cout<<a<<","<<b<<","<<c<<"sunt in progresie aritmetica";

elsecout<<a<<","<<b<<","<<c<<"nu sunt in progresie aritmetica";}

Se citesc 3 valori , sa se arate ca sunt in progresie aritmetica

#include <iostream>using namespace std;void creare(int v[50], int n){int i;for ( i=1;i<=n;i++){ cout<<"\n Elementul ["<<i<<"]=";

cin>>v[i];}}void afisare(int v[50], int n){ int i;for ( i=1;i<=n;i++)cout<<v[i] <<" ";}int main(){int a[50], b[50],c[50];cout <<"\n creaza vectorului a:";creare(a,5);cout <<"\n creaza vectorului b:";creare(b,4);cout <<"\n creaza vectorului c:"; creare(c,6);cout <<"\n afiseaza valorile vectorului a:"; afisare(a,5);cout <<"\n afiseaza valorile vectorului b:"; afisare(b,4);cout <<"\n afiseaza valorile vectorului c: ";afisare(c,6);

return 0;}

Se citesc 3 vectori , sa afiseze cei 3 vectori

#include <iostream>#include<cmath>using namespace std;

void creare (int v[50], int n){ int i;

for ( i=1;i<=n;i++){ cout<<"\n Elementul ["<<i<<"]=";

cin>>v[i];}

}void afisare(int v[50], int n){ int i;

for ( i=1;i<=n;i++)cout<<v[i] <<" ";

}int prim (int x){ int nr_div=0,i;

for (int i=2; i<=sqrt(x); i++)if (x%i==0)

return 0 ;return 1;}

int main(){int a[50],i;cout <<"\n creaza vectorul a:”;

creare(a,5);afisare(a,5);cout<<endl;for ( i=1;i<=5;i++)

if(prim(a[i]))cout<<a[i]<<" ";

return 0;}

Se citeste un vector cu 5 elemente, sa se afiseze numerele

prime

#include <iostream>using namespace std;void creare (int v[50], int n){ int i;

for ( i=1;i<=n;i++){ cout<<"\n Elementul ["<<i<<"]=";

cin>>v[i];}

}void afisare(int v[50], int n){ int i;

for ( i=1;i<=n;i++)cout<<v[i] <<" ";

}

int oglindit(int n){int ogl,cn;cn=n;while (n!=0){ ogl=ogl*10+n%10;n=n/10; }if(cn==ogl)return 1;

elsereturn 0;

}

int main(){int a[10],i,n;cout<<"n= "; cin>>n;creare (a,n);afisare(a,n);for ( i=1;i<=n;i++)

if(oglindit(a[i])!=0)cout<<"Numarul "<<a[i]<<" este palindrom"<<endl;return 0;}

# include <iostream>

# include <cmath>

using namespace std;

int prim (int x)

{ int nr_div=0;

for (int i=2; i<=sqrt(x); i++)

if (x%i==0) nr_div++;

if (nr_div==0) return(1);

else return(0);

}

int main ()

{ int N;

cout << "N="; cin >> N;

if (prim(N))

cout << "PRIM";

else

cout << "NU E PRIM";

return 0;

}

Functia prim este o functie cu

rezultat de tip int, care are un

singur parametru formal x, cel ce

reprezinta numarul de verificat.

Functia va returna valoarea 1

daca numarul x nu are divizori

proprii, deci este numar prim, sau

0 atunci cand numarul x are cel

putin un divizor propriu.

Functia este apelata din cadrul

unei expresii in instructiunea if.

Dupa executia functiei numele ei

va fi inlocuit de valoarea returnata.

int prim (int x)

{ int nr_div=0;

for (int i=2; i<=sqrt(x); i++)

if (x%i==0)

return 0 ;

return 1;

}

if(prim(N)!=0))

Se citesc 3 valori , sa se arate ca sunt in progresie aritmetica

PARAMETRI ACTUALI SI FORMALI

Parametri formali apar în antetul subprogramului şi

sunt utilizaţi de subprogram pentru descrierea

abstractă a unui proces de calcul .

Parametri actuali apar în instrucţiunea de apelare a

uni subprogram şi sunt folosiţi la execuţia unui proces

de calcul pentru valori concrete.

void schimba_valoare (int x, int y)

{ int aux=x; x = y; y = aux; }

int main ()

{ int M=1, N=5;

schimba_valoare(M,N);

cout << "M="<<M<< " " << "N="<<N<<endl;

return 0;

}

Parametrii formali nu sunt variabile. O

variabilă este caracterizată de nume,

tip, şi adresă. Legarea unui parametru

formal la o adresă se realizează în

timpul execuţiei instrucţiunii de apelare

a subprogramului.

//transmitere prin referinta//transmitere prin valoare

void schimba_referinta (int &a, int &b)

{ int aux=a; a=b; b=aux; }

int main ()

{ int M=1, N=5;

schimba_referinta(M,N);

cout << "M="<<M<< " " << "N="<<N<<endl;

#include<iostream.h> int test(int a=10, int b=20) {return a+b;} int main() {cout<<test(30,40)<<endl; //afişează 70 cout<<test(30)<<endl; //afişează 50 cout<<test(); //afişează 30

La apelul subprogramului, parametrilor formali li se atribuie valoarea parametrilor actuali.

Parametrii formali corespunzători parametrilor valoare pot fi iniţializaţi în antetul subprogramului.

Dacă lipseşte un parametru actual, parametrul formal va fi iniţializat cu valoarea din listă

Identificaţi următoarele componente

ale programului (indicaţi liniile unde

sunt folosite):

a) Variabile globale

b) Variabile locale

c) Parametri actuali şi modul de

transfer

d) Parametri formali şi modul de

transfer

e) Antetul funcţiei C

f) Apelul funcţiei C

g) Scrieţi prototipul funcţiei C

Ce afişează apelul func ţiei schimba(a,b) de la lin ia 15 pentru a=15 şi b=27 ?

Ce afişează apelul funcţiei test(a,b) de la linia 9 pentru a=27 şi b=45 ?

#include <iostream>

using namespace std;int test(int &a,int &b){while(a!=b)

if(a>b) a=a-b;else b=b-a;return a;

}int main(){int a=6, b=15;

cout << test(a,b) << " ";cout << a << " "<<b;return 0;

}

Identificaţi următoarele componente ale programului (indicaţi liniile unde sunt folosite): a) Variabile globale b) Variabile locale c) Parametri actuali şi modul de transfer d) Parametri formali şi modul de transfer e) Antetul funcţiei testf) Apelul funcţiei test

g) Scrieţi prototipul funcţiei test

https://drive.google.com/file/d/1z2Clb-6LGobQwhz-iyqanJmtbtv6U1w0/view

pentru suma cifrelor unui număr natural n esteurmătoarea:

int suma (int n)

{

return n%10+suma(n/10);

}

Funcţia este greşită pentru că nu tratează cazurileelementare. Ca urmare, recursia nu se opreşteniciodată.Pentru a calcula suma cifrelor, se elimină succesivtoate cifrele sale, până când n devine 0. Din acestmoment, se evaluează la infinit suma(0),deoarece 0/10 este permanent 0.

Recursivitate

int suma (int n){

if(n<=0) return 0;

return n%10+suma(n/10);}

Funcţia corectă ar fi fost:

Definiție

O funcție se numește recursivă dacă ea se autoapelează.Clasificare

Recursivitatea este de două tipuri: directă și indirectă.În cazul în care auto-apelul se realizează în cadrul aceleiași funcții, recursivitatea este directă (A->A).Atunci când auto-apelul se realizează prin intermediul altei funcții, recursivitatea este indirectă (A->B->...->A).

O funcţie greşită

Funcţie recursivă directă:int fact(int n)

{

if(n==1)

return 1;

return n*fact(n-1); //apel recursiv

}

int f(int a)

{

if(a%12==0)

return 0;

return f(a-1);

}

int f(int b)

{

if(b/2>2)

return b+f(b/2);

return b/2;

}

int f1(int d)

{

while (d%2==0)

return

++c+f2(d/2);

return 1;

}

int f2(int e)

{

if (e%2==0)

return f1(e);

return 0;

}

int f(int g)

{

if(x/3)>0;

return x/3;

return x*3;

}

int f(int c)

{

while(c>1)

return c+f(c-1);

return 1;

}

int f(int a)

{

if (a%3==0)

return 0;

return 1+f(a-1)

}

void f(int x, int &y)

{

if(x==y) cout<<x<<y;

else

{x++; y--; f(x,y); cout<<x<<y}

}

int f(int b, int c)

{

if(b>c)

if(b%c==0)

return f(b+b/c,c);

else

return 1+f(b+b%c,c);

return b;

}

int f(int x, int d)

{

while(x>0)

{

if(x==d)

return 1;

if(x%d==0)

return 1+ f(x/d, d+1)

return f(x-1, d);

}

return 0;

}

Matrici• Numim tablou o colecţie ( grup, mulţime ordonată ) de date • de acelaşi tip ,• situate într-o zona de memorie continuă ( elementele tabloului se află la adrese

succesive).

X[1][1] X[1][2] X[1][3] ……….. X[1] [m]

X[2][1] X[2][2] X[2][3] ………. X[2] [m]

X[3][1] X[3][2] X[3][3] ………… X[3] [m]

……….. …………. ………….. ………… ……………

X[n][1] X[n][2] X[n][3] ……… X[n][m]

matrici#include<iostream>using namespace std;int main (){int x[10][10], n, m, i, j;cout<<"Dati numarul de linii: "; cin>>n;cout<<"Dati numarul de coloane: "; cin>>m;cout<<"Introduceti elementele matricei: "<<endl;for (i=1; i<=n; i++) //parcurge liniilefor (j=1; j<=m; j++) //parcurge coloanele{cout<<"x["<<i<<"]["<<j<<"]="; //afiseaza ce locatie de memorie

cin>>x[i][j]; //memoreaza valoarea in locatie

}cout<<"Afisam matricea: "<<endl;for (i=1; i<=n; i++){for (j=1; j<=m; j++)

cout<<x[i][j]<<" "; // sa afiseze elementele din randul i

cout<<endl; // pentru a trece la randul i+1

}return 0;

}

Se citeste o matrice patratica. Sa se afiseze elementele de pe diagonala secundara, elementele de pe diagonala principala, elementele de sub/desupra diagonalei secundare/principala.

Este un caz particular de matrice pentru care numărul de linii este egal cu numărul de coloane.

Diagonala principală este formată din elementele care îndeplinesc relația i=j

Citeste matricea;Afiseaza elementele matricei;cout<<"Afisam elementele diagonalei principale: "<<endl;for (i=1; i<=n; i++)

{for (j=1; j<=m; j++)

if(i==j) cout<<x[i][j]<<" ";

cout<<endl;}

x11 x12 x13 X1….m

x21 x22 x23 X2…m

x31 x32 x33 X3…..m

xn1 xn2 xn3 xnm

Diagonala secundară conţine elementele caracterizate de relaţia i+j=n+1.

Citeste matricea;Afiseaza elementele matricei;cout<<"Afisam elementele diagonalei secundara: "<<endl;for (i=1; i<=n; i++)

{ for (j=1; j<=m; j++)

if(i+j==n+1) cout<<x[i][j]<<" ";

cout<<endl;}

x11 x12 x13 X1….m

x21 x22 x23 X2…m

x31 x32 x33 X3…..m

xn1 xn2 xn3 xnm

cout<<"Afisam elementele de deasupra diagonalei principale:"<<endl;for (i=0; i<n; i++){for (j=0; j<m; j++)

if(i<j)cout<<x[i][j]<<" ";

cout<<endl;}

Citeste matricea;Afiseaza elementele matricei;

x11 x12 x13 X1….m

x21 x22 x23 X2…m

x31 x32 x33 X3…..m

xn1 xn2 xn3 xnm

cout<<"Afisam elementele de sub diagonala principală : "<<endl;for (i=1; i<=n; i++){for (j=1; j<=m; j++)

if(i>j)cout<<x[i][j]<<" ";

cout<<endl;}

Citeste matricea;Afiseaza elementele matricei;

x11 x12 x13 X1….m

x21 x22 x23 X2…m

x31 x32 x33 X3…..m

xn1 xn2 xn3 xnm