Documente Academic
Documente Profesional
Documente Cultură
Culegere
Culegere
CULEGERE DE PROBLEME
// PI=3.14
#include <stdio.h>
#include <values.h>
// afisare valoare maxima dintr-un sir
void main () {
int n,i, a,amax;
printf("n="); scanf("%d",&n);
amax=-MAXINT;
// cel mai mic intreg
for (i=0;i<n;i++) {
scanf("%d",&a);
if (amax < a)
amax=a;
}
printf("%d\n",amax);
}
E1.22 Citirea unui sir de numere terminat cu caracterul "End of File"
recunoscut de sistem ( Ctrl-Z in DOS si Windows).
#include <stdio.h>
// suma valorilor dintr-un sir de numere
void main () {
float a,sum;
sum=0;
while ( scanf("%f",&a) != EOF)
sum=sum+a;
printf("%f \n",sum);
}
E1.23 Citirea mai multor siruri de numere terminate fiecare cu un zero.
Sfarsitul datelor este marcat tot cu zero. Exemplu:
123045078900
#include <stdio.h>
// sume valori din mai multe siruri terminate cu zero
void main () {
float a,sum,m;
do {
m=sum=0;
// m=lungime sir, sum = suma sir
do {
scanf("%f",&a);
// un numar a dintr-un sir
if (a==0) break;
sum=sum+a; m++; // aduna a la suma si numara
} while (a);
if (m)
// daca sir de lungime nenula
printf("%f \n",sum);
} while (m);
}
Obs. Situatia de mai sus apare la verificarea unor programe cu mai multe
seturi de date (memorate probabil intr-un fisier), printr-o singura rulare
a fiecarui program.
E1.24 Afisarea unui numar intreg fara semn in binar folosind extragerea
selectiva de biti cu o masca ce contine un singur bit 1.
void main () {
int n;
// un intreg
printf("n= "); scanf("%d",&n);
unsigned int mask = 1<<15;
// bitul 15 =1, ceilalti zero (128)
while (mask) {
printf ("%d", (mask & d) ? 1: 0);
mask >>= 1;
// deplasare masca la dreapta cu un bit
}
printf("\n");
}
E1.25 Determina cel mai mare divizor comun a doi intregi (ineficient).
void main () {
int a,b,d;
printf ("a,b: "); scanf("%d%d",&a,&b);
d= a< b ? a : b;
// d= minim(a,b);
while ( a%d || b%d ) // cat timp d nu este divizor comun
d=d-1;
printf ("cmmdc=%d\n",d);
}
E1.26 Determina cel mai mare divizor comun a doi intregi (alg. lui Euclid).
void main () {
int a,b,r;
printf ("a,b: "); scanf("%d%d",&a,&b);
while (r = a%b) {
a=b; b=r;
}
printf ("cmmdc= %d\n", b);
}
E1.28 Ciclu in ciclu. Numararea numerelor prime mai mici ca un intreg dat n.
#include <stdio.h>
main () {
int n,m,d,np ;
printf ("n= "); scanf ("%d",&n);
if (n < 4) {
printf ("%d\n",n);
// primele 3 numere prime
return;
}
np=3;
// vor fi cel putin 3 numere prime
for (m=5;m<=n;m=m+2) { // incearca numerele impare m
for (d=3;d<m;d=d+2)
// cu toti divizorii posibili d
if (m % d ==0)
break;
if (d>=m)
// daca m este prim
np++;
// contor de numere prime
}
printf ("%d\n",np);
}
E1.29 Suma unei serii definite printr-o relatie de recurenta intre termeni.
// suma seriei Taylor pentru e^x cu precizie maxima permisa de "float"
void main () {
float x,y,t; int k;
scanf ("%f",&x);
y=0;
// suma seriei
t=1; k=1;
// t = termen curent
while ( t > 0) {
// termenii scad cand creste k
y=y+t;
// aduna termen la suma
t=t*x/k;
// calcul termen urmator
k++;
// rang termen
}
printf ("%15.6f %15.6f \n",y, exp(x));
}
// varianta cu instructiunea "for"
void main () {
float x,y,t; int k;
scanf ("%f",&x);
y=0;
// suma seriei
for (k=1,t=1; t> 0; k++) {
y=y+t;
// aduna termen la suma
t=t*x/k;
// calcul termen urmator
}
printf ("%15.6f %15.6f \n",y, exp(x));
}
E1.30 Program care afiseaza un meniu de optiuni si trateaza fiecare optiune
#include <stdio.h>
#include <conio.h>
void main () {
int a,b;
char opt;
// cod optiune (un caracter)
do {
// afisare meniu
clrscr();
// sterge ecran
printf ("\n\t A = Adunare \n\t S = Scadere \n\t M = inmultire");
printf("\n\t D = Impartire \n\t \n\t X = Iesire \n\n");
printf ("\t Optiune: ");
// citire si tratare optiune
fflush(stdin); opt=getchar();
if (opt=='x' || opt=='X') return;
printf ("\n\t Doi intregi: "); scanf("%d%d",&a,&b);
printf("\n\t Rezultat=");
switch (opt) {
case 'a': case 'A': printf (" %d", a+b); break;
case 's': case 'S': printf (" %d", a-b); break;
case 'm': case 'M': printf (" %d", a*b); break;
case 'd': case 'D': printf (" %d", a/b); break;
}
fflush(stdin); getchar();
} while (1);
}
E1.31 Afisarea in hexazecimal a octetilor din mai multe numere de tip "float"
void main () {
float f;
char *p; int i;
// afisare octeti in hexa (float)
for ( f=0; f<10;f=f+0.5) {
printf ("%6.2f\t",f);
// afisare numar
p=(char*) &f;
// adresa primului octet
for (i=0;i<sizeof(f);i++) // afisare octeti
printf("%02x ", *p++); // pe cate 2 cifre hexa, cu spatii intre ei
printf("\n");
}
}
PROBLEME PROPUSE
P1.1 Program care citeste coordonatele (x,y) ale unui punct din plan si
afiseaza numarul cadranului in care se afla (1,2,3,4). Se vor verifica
succesiv semnele valorilor x si y. S-ar putea folosi instructiunea "switch"?
P1.2 Program pentru calculul sumei a doua intervale de timp exprimate
in ore, minute si secunde, cu si fara instructiunea 'if'. (rezultatul este
exprimat tot in ore, minute, secunde). Exemplu :
h1:m1:s1 = 02:49:48 ; h2:m2:s2 = 10:17:35
rezultat = 13:07:23
P1.3 Program pentru calculul timpului scurs intre doua momente de timp
exprimate in ore, minute si secunde (cu si fara "if"). Exemplu :
h1:m1:s1 = 13:07:23 ; h2:m2:s2 = 02:49:48
rezultat = 10:17:35
P1.4 Program pentru determinarea celui mai mare intreg pentru care se mai
poate calcula corect factorialul sau, succesiv pentru tipurile "int",
"long", "float" si "double".
Indicatie: Se compara k!/k cu (k-1)! si daca difera se afiseaza k.
P1.5 Program care aduna valoarea x de n ori, ca "float" si ca "double", si
afiseaza sumele sx si sy. sx este de tip "float",iar sy de tip "double".
Se vor lua pe rnd :
x=0.1 n=100
x=0.01 n=1000
x=0.001 n=10000
Se vor afisa sumele partiale la fiecare n/10 termeni adunati, cu pauza
dupa fiecare 10 linii afisate ( pauza realizata cu functia "getchar").
P1.6 Program pentru calculul combinarilor de n luate cite m , pentru n=10
si m intre 1 si 10, prin doua metode :
(a) Folosind relatia de recurenta:
C(n,k) = C(n,k-1) * (n-k+1)/k ptr. k=1,m si C(n,0)=1
(b) Folosind relatia de calcul:
C(n,m) = n!/ (m!*(n-m)!)
P1.7 Program pentru afisarea echivalentului binar al unui numar natural
(intreg cu semn) dat. Exemple: 11=1011, 25 =1001, 23= 10111.
Algoritm: Se repeta impartirea la puteri descrescatoare ale lui 2, iar
caturile sunt cifrele binare. Restul impartirii devine noul deimpartit.
Varianta: se foloseste o masca binara cu un singur bit 1 (deplasat mereu
la dreapta), cu care se extrag biti succesivi din numar.
P1.8 Program pentru calculul si afisarea radacinii patrate a unor numere
folosind urmatoarea relatie de recurenta intre doua aproximatii succesive
r1 si r2 ale radacinii lui x : r2 = ( r1 + x/r1)/2 .
Aproximatia initiala r1 poate fi orice valoare ( se va lua r1=x/2).
Relatia de recurenta se aplica atata timp cat r1 este diferit de r2.
Se va afisa pentru verificare si rezultatul functiei sqrt(x), pentru
primele 20 de numere pare.
P1.9 Program pentru afisarea tuturor numerelor naturale de 2 cifre care
au cel putin 7 divizori nebanali (altii decit 1 si numarul respectiv).
P1.10 Program pentru afisarea numarului maxim de divizori ai unui numar
natural de n cifre ( n<=5 sau n<=10). Se va completa programul cu afisarea
celui mai mare (celui mai mic) numar cu numar maxim de divizori.
P1.11 Program pentru afisarea tuturor descompunerilor unui numar natural
dat prin sume de numere naturale consecutive. Exemplu:
15 = 1+2+3+4+5 = 4+5+6 = 7+ 8
P1.12 Program pentru afisarea numerelor perfecte mai mici ca o valoare data.
(Un numar perfect este un numar egal cu suma tuturor divizorilor sai).
P1.13 Program care calculeaza valoarea functiilor sin(x) si cos(x) ca suma a
seriei de puteri si afisare alaturi de rezultatul functiilor de biblioteca.
sin(x) = x - x^3/3! + x^5/5! - x^7/7! + ...
cos(x) = 1 - x^2/2! + x^4/4! - x^6/6! + ...
Se vor insuma toti termenii mai mari ca zero in valoare absoluta.
Observati ce se afiseaza pentru valori mari ale lui x si de ce este necesara
//
R1.1
// afisare pozitie punct fata de cele 4 cadrane
#include <stdio.h>
void main () {
float x,y;
printf("x,y : "); scanf("%f%f",&x,&y);
if (x==0 && y==0)
printf("In origine (0,0) \n");
else
if (x==0 || y==0)
printf("Pe una din axe \n");
else
if (x > 0 )
if (y > 0)
printf ("Cadranul I \n");
else
printf ("Cadranul IV \n");
else
if (y > 0)
printf ("Cadranul II \n");
else
printf ("Cadranul III \n");
}
//
R1.2
void main () {
int h1,m1,s1, h2,m2,s2, h,m,s;
printf("timp1="); scanf("%d%d%d",&h1,&m1,&s1);
printf("timp2="); scanf("%d%d%d",&h2,&m2,&s2);
// adunare timpi (cu if)
s=s1+s2; m=h=0;
if (s >=60) {
s=s-60; m=1;
}
m=m1+m2+m;
if (m >=60) {
m=m-60; h=1;
}
h=h1+h2+h;
// afisare rezultat
printf ("%02d:%02d:%02d \n",h,m,s);
}
//
R1.3
void main () {
int h1,m1,s1, h2,m2,s2, h,m,s;
long t1,t2,t; int r;
printf("timp1="); scanf("%d%d%d",&h1,&m1,&s1);
printf("timp2="); scanf("%d%d%d",&h2,&m2,&s2);
// scadere timpi (fara if)
t1= 3600L*h1 + 60*m1 + s1;
t2= 3600L*h2 + 60*m2 + s2;
t=t1-t2;
h= t/3600;
r=t%3600;
m=r/60;
s=r%60;
printf ("%02d:%02d:%02d \n",h,m,s);
}
//
R1.4
// cel mai mare numar k pentru care se poate calcula k!
#include <stdio.h>
void main () {
int k;
double kf2,kf1=1; // sau: int, long, float
for (k=1;k<30;k++) {
kf2=kf1*k;
if (kf2/k !=kf1) {
printf ("%d ",k);
break;
}
else
kf1=kf2;
}
}
//
R1.5
// erori la calcule cu numere reale
#include <stdio.h>
void main () {
float x, sx; double sy;
int i,k, n=100;
x=0.1;
for (k=0;k<3;k++) { // pentru 0.1, 0.01 si 0.001
sx=sy=0.;
for (i=1;i<=n;i++){
sx=sx+x;
sy=sy+(double)x;
if ( i % (n/10) ==0)
printf ("%f %lf \n", sx, sy);
}
n=n*10; x=x/10;
getchar();
}
}
//
R1.6
// calcul combinari prin doua metode
#include <stdio.h>
void main () {
int k,n,m, c1, c2; long f1,f2,f3;
n=10;
for (f1=1,k=1;k<=n;k++)
f1=f1*k;
for (m=1;m<=10;m++) {
// c1 prin metoda (a)
c1=1;
for (k=1;k<=m;k++)
c1=c1*(n-k+1)/k;
// c2 prin metoda (b)
for (f2=1,k=1;k<=m;k++)
f2=f2*k;
// f1 = n!
// f2= m!
for (f3=1,k=1;k<=n-m;k++)
f3=f3*k;
// f3 = (n-m)!
c2=f1/(f2*f3);
printf("%4d %8d %8d \n", m,c1,c2);
}
}
//
R1.7
// cifrele binare sunt caturi ale impartirii prin puteri ale lui 2
void main () {
int n,d=1;
printf ("\n n= "); scanf("%i",&n);
while ( d <= n)
// d = puterea lui 2 imediat inferioara lui n
d=d*2;
d=d/2;
while ( d>=1) {
printf ("%i", n/d);
// catul este cifra binara
n=n%d; d=d/2;
// continua cu restul impartirii
}
}
// afisare intreg in binar, cu extragere de biti succesivi
void main () {
int n;
printf ("\n n= "); scanf("%i",&n);
unsigned int mask = 1<<15;
// bitul 14 =1, ceilalti zero
while (mask) {
printf ("%c", (mask & n) ? '1': '0');
mask >>= 1;
// deplasare masca la dreapta cu un bit
}
}
//
R1.8
// calcul radacina patrata prin aproximatii succesive
#include <stdio.h>
#include <math.h>
void main () {
float x, r1,r2;
for (x=2;x<41;x=x+2) { // ptr 20 de numere pare
r2=x/2.;
// aproximatie initiala
do {
r1=r2;
// aprox. noua r2 devine aprox. veche r1
r2= (r1+x/r1)/2.; // se calc. o noua aproximatie r2
} while ( r1 != r2); // cat timp difera la primele 6 zecimale
//
R1.9
// numere de 2 cifre cu peste 6 divizori
void main () {
int nr,k,i,m;
nr=99;
printf ("\n");
// calcul numar de divizori
for (k=nr;k>=10;k--) { // incearca numere de 2 cifre k
m=0;
// m=nr divizori ai lui k
for (i=2;i<k;i++)
if ( k % i == 0)
++m;
if ( m >= 7)
printf ("%d ",k);
}
}
//
R1.10
// nr maxim de divizori ptr un numar de n cifre
void main () {
long n,n1,n2,m,max,k,i,nr1,nr2;
printf ("n= "); scanf ("%ld",&n);
n1=pow(10,n)-1;
// nr maxim de n cifre
n2=pow(10,n-1);
// nr minim de n cifre
max=1;
// nr maxim divizori
for (k=n1;k>=n2;k--) {
// ptr fiecare numar de n cifre
m=0;
// nr divizori ai lui k
for (i=2;i<=k/2;i++)
// incearca toti divizorii posibili
if ( k % i == 0)
++m;
// m este nr de divizori ai lui k
if (m==max)
nr1=k;
// nr1 este cel mai mic numar gasit
if ( max < m) {
max=m; nr2=k;
// nr2 este cel mai mare numar gasit
}
}
printf ("%ld si %ld au %ld divizori \n", nr1, nr2, max);
}
//
R1.11
// toate secventele de numere naturale consecutive
// a caror suma este egala cu n
main () {
int n,k,i,j,l,s;
printf("n= "); scanf ("%d",&n);
k= n/2+1;
// pentru a nu se repeta secvente
for (i=1;i<k;i++) {
s=i;
// inceput posibil de secventa
for (j=i+1;j<=k; j++) { // j = numere din secventa
s=s+j;
// suma numerelor din secventa
if (s>=n)
break;
}
/* afisare numere ntre i si j */
if (s==n) {
for (l=i;l<=j;l++)
printf ("%d ",l);
printf ("\n");
}
}
}
//
R1.12
/* numere perfecte */
void main () {
int n,m,s,d ;
printf("n="); scanf("%d",&n);
for (m=2; m<=n ;m++) {
s=0;
for (d=1; d<m ; d++) {
if ( m % d==0)
s=s+d;
}
if (m==s)
printf ("\n %d", m);
}
}
//
R1.13
// suma seriei Taylor pentru sin(x) si cos(x) cu precizie maxima
void main () {
float x,sx,cx,ts,tc; int k;
scanf ("%f",&x);
sx=cx=0; ts=x; tc=1; // ts, tc = termeni din seriile sin si cos
//
R1.14
// Determina numarul de zerouri cu care se termina produsul
// a n numere naturale date (fara efectuare produs)
#include <stdio.h>
void main () {
int n,a,b,n2,n5,i ;
n2=n5=0;
// numar de cifre 2 si 5 in produs
scanf ("%d",&n);
// cite numere se citesc
for (i=0;i<n;i++) {
scanf ("%d",&a);
// un numar natural
b=a;
while ( b%2==0) {
n2++; b=b/2;
}
while ( a%5 ==0) {
n5++; a=a/5;
}
}
if ( n2<n5)
printf ("%d\n",n2);
else
printf ("%d\n",n5);
}
//
R1.15
/* descompunere in factori primi */
#include <stdio.h>
main () {
int n,m,k,p ;
printf ("n= "); scanf ("%d",&n);
m=n;
for (k=2; k<=n && m>1; k++) {
p=0;
// putere a factorului k
while (m%k ==0) {
// cat timp m se imparte prin k
p++; m=m/k;
}
if (p > 0)
// daca m s-a impartit exact prin k
printf ("%d^%d*",k,p);
// k este un factor prim, p este puterea sa
}
printf ("\b\n");
}
Obs. In expresia (i<n && b!=a[i]) ordinea celor 2 conditii este esentiala !
E2.5 Declarare si utilizare matrice
// Generare matrice unitate
#define M 20
// nr maxim de linii si de coloane
void main () {
float unit[M][M];
int i,j,n;
printf("nr.linii/coloane: "); scanf("%d",&n);
if (n > M) return;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
if (i !=j )
unit[i][j]=1;
else
unit[i][j]=0;
...
}
E2.6 Initializare matrice cu zerouri
// Generare matrice unitate
#define M 20
// nr maxim de linii si de coloane
void main () {
float u[M][M]={0};
int i,j,n;
printf("nr.linii/coloane: "); scanf("%d",&n);
for (i=0;i<n;i++)
u[i][i]=1;
...
}
E2.7 Citire-scriere matrice de reali
void main () {
int nl,nc,i,j; float a[20][20];
// citire matrice
printf("nr.linii: "); scanf("%d",&nl);
printf("nr.coloane: "); scanf("%d",&nc);
if (nl >20 || nc >20) {
printf("Eroare: dimensiuni > 20 \n"); return;
}
for (i=0;i<nl;i++)
for (j=0;j<nc;j++)
scnaf ("%f", &a[i][j]);
// afisare matrice
for (i=0;i<nl;i++) {
for (j=0;j<nc;j++)
printf ("%f ",a[i][j]);
printf ("\n");
}
}
PROBLEME PROPUSE
P2.1 Program care citeste un sir de note si calculeaza media notelor de
trecere ( >= 5) si ponderea notelor sub 5 in totalul notelor (procentual).
P2.2 Program care citeste un sir de note (intre 0 si 10) si calculeaza
procentul de note din fiecare valoare posibila ( se afiseaza 10 procente
a caror suma este 100).
P2.3 Program care citeste n numere reale X si m+1 numere intregi A si
afiseaza numarul de valori X situat in fiecare din cele m intervale
delimitate de valorile din A. Se verifica daca valorile A sunt introduse
in ordine crescatoare si in caz contrar programul se opreste.
P2.4 Program care citeste doi vectori neordonati de numere distincte si
verifica daca ei contin aceleasi numere, indiferent de ordine (fara
ordonarea lor). Se poate folosi programul scris si pentru vectori cu
elemente repetate diferit in cei doi vectori ? (Ex: {2,1,2,3}, {3,2,1,3})
P2.5 Program pentru interclasarea a doi vectori ordonati intr-un singur
vector ordonat, care se va afisa.
Exemplu de date : a={2,4,6,7}, b={1,3,9,11};
Rezultat: 1,2,3,4,6,7,9,11
P2.6 Program pentru citirea unui vector de intregi si extragerea
elementelor distincte intr-un al doilea vector, care se va afisa.
P2.7 Program pentru ordonarea unui vector de numere intregi prin metoda
bulelor: se compara elemente vecine din vector (a[i] si a[i+1] ) si, daca
este necesar, se schimba intre ele pentru ca a[i] <= a[i+1]. In general
sunt necesare mai multe treceri prin vector pentru ordonarea sa. Variante:
(a) Numarul de treceri este egal cu dimensiune vector minus 1.
(b) Se fac atatea treceri cate sunt necesare pentru ordonarea vectorului
(se memoreaza daca au fost necesare schimbari de elemente in vector si se
opreste repetarea cand nu a mai fost necesara nici o schimbare).
(c) O trecere prin vector se face de la prima la ultima pereche
(d) O trecere prin vector se face de la ultima pereche catre prima pereche
//
R2.1
// media studentilor integralisti si ponderea restantierilor
#include <stdio.h>
void main () {
int n, nota[200];
int i, m, s; // m =nr note > 5, s= suma note > 5
// citire date
n=0;
while ( scanf("%d", ¬a[n]) != EOF)
++n;
// numarare si insumare note peste 5
m=s=0;
for (i=0;i<n;i++)
if ( nota[i] >= 5) {
++m; s=s+nota[i];
}
if ( m )
printf(" Medie integralisti= %5.2f \n", (float)s/m );
printf (" Procent restantieri= %5.2f % \n", 100.*(n-m)/n);
}
//
R2.2
// statistica notelor unor elevi
#include <stdio.h>
void main () {
int n, nota[200], nn[11];
//nn[k] = numar note egale cu k
int i,j;
// citire note
n=0;
while ( scanf("%d", ¬a[n]) != EOF)
++n;
// initializare contoare (sau la declarare)
for (j=1;j<11;j++)
nn[j]=0;
// numarare note din fiecare clasa
for (i=0;i<n;i++)
for (j=1;j<=10;j++)
if (nota[i] == j)
nn[j] ++;
// afisare procente
for (j=1;j<=10;j++)
printf ( "%5.2f %c note de %d \n", 100.*nn[j]/n, '%', j);
}
//
R2.3
// clasifica n valori X in m intervale cu limitele A
#include <stdio.h>
void main () {
float x[500]; int a[100];
int nr[100]={0};
// init. vector nr
int n,m,i,j; float y;
// citire date
printf ("n="); scanf("%d",&n);
for (i=0;i<n;i++) {
scanf("%f",&y); x[i]=y;
// ptr. Borland C 2.0
}
printf ("m="); scanf("%d",&m);
for (i=0;i<=m;i++)
scanf("%d",&a[i]);
// verifica daca vectorul a este ordonat
for (i=0;i< m;i++)
if (a[i] >= a[i+1] ) {
printf("limite neordonate \n");
return;
// iesdire din main
}
// numara valorile din fiecare interval
for (i=0;i<n;i++)
for (j=0;j<=m;j++)
if ( x[i] > a[j] && x[i] <=a[j+1])
nr[j+1]++;
// afisare contoare
for (j=1;j<=m;j++)
printf ("%4d valori in intervalul %d \n", nr[j],j);
}
//
R2.4
// comparatie de vectori neordonati
#include <stdio.h>
void main () {
int n, a[]={3,1,4,2,5}, b[]={1,5,3,2,4};
int egale, este, i,j;
egale=1;
// presupunem ca sunt egali
n=sizeof(a)/sizeof(a[0]); // dimensiune vector a
for (i=0;i<n;i++) {
este = 0;
for (j=0;j<n;j++)
// cauta pe a[i] in vectorul b
if (a[i] == b[j])
este =1;
// daca a[i] este in b
if ( ! este ) {
egale=0; break;
// daca a[i] nu este in b vectori diferiti
}
}
printf (egale ? "egale\n":"diferite\n");
}
Obs. Programul se simplifica daca se defineste o functie de cautare a
unui numar intr-un vector.
//
R2.5
// interclasare vectori ordonati
void main () {
int a[100], b[100], c[200];
int na, nb, nc, ia, ib, ic, k;
// citire vectori si verificare ordonare
...
// interclasare
ia=ib=ic=1;
while ( ia <= na && ib <= nb) {
// cat timp exista elem in a si in b
if ( a[ia] < b[ib] )
c[ic++]=a[ia++]; // scoate in c pe minim (a[i],b[j])
else
c[ic++]=b[ib++];
}
// copiaza in c elem. ramase in a sau in b
for (k=ia;k<=na;k++)
c[ic++]=a[k];
for (k=ib;k<=nb;k++)
c[ic++]=b[k];
nc=--ic;
// dimensiune vector rezultat
// afisare vector rezultat
for (k=1;k<=nc;k++)
printf ("%d ",c[k]);
}
//
R2.6
// extragere elemente distincte dintr-un vector
#include <stdio.h>
void main () {
int a[]={ 3,2,5,1,3,4,6,4,1,6,5};
// un vector de intregi
int b[100];
// aici se pun elementele distincte din a
int n,m,i,j, gasit;
n=sizeof(a)/sizeof(a[0]);
m=0;
// dimensiune vector b
for (i=0;i<n;i++) {
//
R2.7
// ordonare prin metoda bulelor (var. a)
#include <stdio.h>
void main () {
int a[300];
// un vector de intregi
int n,i,j, aux;
// citire vector
n=-1;
while (scanf("%d",&a[++n]) > 0) ; // repeta instr vida !
// repeta de n-1 ori
for (j=1;j<n;j++)
// compara n-1 perechi vecine
for (i=0;i<n-1;i++)
if ( a[i] > a[i+1] ) {
// nu sunt in ordine
// schimba pe a[i] cu a[i+1]
aux=a[i]; a[i]=a[i+1]; a[i+1]=aux;
}
// afisare vector ordonat
for (i=0;i<n;i++)
printf ("%4d",a[i]);
}
// ordonare prin metoda bulelor (var. b)
#include <stdio.h>
void main () {
int a[300];
// un vector de intregi
int n,i,j, aux, gata;
// citire vector
n=-1;
while (scanf("%d",&a[++n]) > 0) ; // repeta instr vida !
// repeta cat timp mai sunt schimbari
do {
gata =1;
// compara n-1 perechi vecine
for (i=0;i<n-1;i++)
if ( a[i] > a[i+1] ) {
// nu sunt in ordine
// schimba pe a[i] cu a[i+1]
aux=a[i]; a[i]=a[i+1]; a[i+1]=aux;
gata =0;
}
} while ( ! gata);
// afisare vector ordonat
for (i=0;i<n;i++)
printf ("%4d",a[i]);
}
//
R2.8
// sortare prin selectie directa (aduce valori mici la inceput)
#include <stdio.h>
void main () {
int a[500];
// un vector de intregi
int n,i,j, aux;
// citire date
n=-1;
while (scanf("%d",&a[++n]) > 0) ; // repeta instr vida !
// ordonare
for (i=0;i<n-1;i++)
// se aduce minim dintre a[i+1]...a[n-1] in pozitia i
for (j=i+1;j<n;j++)
if ( a[j] < a[i] ) { //muta pe a[j] in pozitia i
aux = a[i]; a[i]=a[j]; a[j]=aux;
}
// scrie vector ordonat
for (i=0;i<n;i++)
printf ("%d ",a[i]);
}
//
R2.9
// sortare prin selectie directa (aduce valori mari la sfarsit)
#include <stdio.h>
void main () {
int a[500];
// un vector de intregi
int x, y, px;
// x=valoare ptr care se calculeaza polinom
n=sizeof(c)/sizeof(c[0]);
// nr de coeficienti
while (scanf("%d",&x)==1) {
// repeta ptr mai multe valori x
// metoda 1: ca suma de termeni calculati separat
y=c[n];
// suma initiala
for (i=0;i<n;i++)
y=y+ pow(x,n-1-i) *c[i];
printf ("%d ",y);
// metoda 2: termeni calculati prin recurenta
y=c[n-1]; px=1;
// suma initiala
for (i=n-2;i>=0;i--) {
px=px*x;
// puterea lui x (x^i)
y=y+ px*c[i];
}
printf ("%d ",y);
// metoda 3 : relatie de recurenta intre polinoame
y=0;
// polinom de grad 0
for (i=0;i<n;i++)
y=y*x+c[i];
printf ("%d \n",y);
}
}
//
R2.12
// valoare polinom de interp. Newton
#include <stdio.h>
void main () {
float xx,yy,p; int i,j,n;
float c[]= { 1,2,3,4,5}, x[]={0,2,4,6,8};
n=4;
xx=5;
// mai putin eficient
yy=c[0];
for (i=1;i<=n;i++) {
p=1;
for (j=1;j<=i;j++)
p=p*(xx-x[j]);
yy = yy + c[i]*p;
}
printf ("%f ",yy);
// mai eficient
yy=c[0];
p=1;
for (i=1;i<=n;i++) {
p=p*(xx-x[i]);
yy = yy + c[i]*p;
}
printf ("%f \n",yy);
}
//
R2.13
// norma unei matrice (cu numerotare de la 1 ptr linii si col)
#include <math.h>
#include <stdio.h>
#define M 20
// dimensiuni maxime matrice
void main () {
int n=3,m=3;
// n linii, m coloane
float a[M][M] = { {0,0,0,0}, {0,3,-6,2}, {0,1,4,-5}, {0,-7,3,6} };
int i,j; float s, smax;
smax=0;
for (i=1;i<=n;i++) {
s=0;
for (j=1;j<=m;j++)
s=s+ abs (a[i][j]);
if ( smax < s)
smax=s;
}
printf ("%f \n", smax);
}
//
R2.14
// valoare in "sa" dintr-o matrice
// minim dintre val. maxime pe linii
#include <stdio.h>
#include <math.h>
#define M 20
// nr maxim de linii/coloane
void main () {
int n=3,m=3;
// n linii, m coloane
float a[M][M] = { {0,0,0,0}, {0,3,-6,2}, {0,1,4,-5}, {0,-7,3,6} };
int i,j; float min, max;
min = 1e30;
for (i=1;i<=n;i++) {
max=a[i][1];
for (j=1;j<=m;j++)
if (max < a[i][j])
max=a[i][j];
if (min > max)
min =max;
}
printf ("%f \n", min);
}
//
R2.15
// secventa ordonata de lungime maxima
#include <stdio.h>
void main () {
int a[100] = {5,3,6,7,2,4,6,8,4,1,9,0}; // un sir terminat cu zero
int i,j,imax,l, lmax; // imax,lmax = inceput si lungime secventa maxima
imax=i=0; lmax=0;
// sau lmax=1
while (a[i]) {
// repeta pana la sfarsit sir
j=i;
// ultimul din secventa
while ( a[j+1] && a[j]<=a[j+1])
j++;
l= j-i+1;
// lungime secventa intre i si j
if ( lmax<l) {
lmax=l; imax= i;
}
i=j+1;
// continua cautarea din poz. j+1
}
printf ("\n %d \n", lmax); // lungime secventa
for (i=imax; i<imax+lmax;i++)
printf ("%d ", a[i]);
}
//
R2.16
# include <stdio.h>
# define M 30 // nr. maxim noduri graf
void main () {
int n, nv, max ;
// n=nr de noduri, nv=nr de vecini
int a[M][M] ; // matrice de adiacente graf
int i,j, imax ;
// citire date
printf (" nr. noduri: "); scanf ("%d",&n);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
a[i][j] =0;
printf ("perechi de noduri adiacente: ");
while ( scanf("%d%d", &i,&j)> 0) {
a[i][j] = a[j][i]=1;
}
// determina nod cu nr maxim de vecini
max=0; imax=0;
// nr maxim de vecini
for (i=1;i<=n;i++) {
// ptr fiecare nod i
nv=0;
// nr de vecini nod i
for (j=1;j<=n;j++)
// ptr fiecare posibil vecin
if (a[i][j])
// daca muchie i-j atunci
++nv;
// s-a mai gasit un vecin al lui i
}
j=indexOf(val,n,q);
if (j < 0) {
val[++n]=q; j=n; cls[n]= ++cl;
}
unif(cls,n,i,j);
}
// afisare clase
for (i=1;i<=cl;i++) {
m=0;
for (j=1;j<=n;j++)
if (cls[j]==i) {
printf("%d ",val[j]);
m++;
}
if (m)
printf("\n");
}
}
u[i][j]=0;
u[i,i]=1;
}
}
// afisare matrice patratica (cu 30 de coloane declarate)
void scrmatr (float a[][30], int n) {
int i,j;
for (i=0;i<n;i++) {
for (j=0;j<n;j++)
printf ("%4.0f",a[i][j]);
printf("\n");
}
}
// utilizare
void main () {
float x[30][30]; int n;
for (n=2;n<=10;n++) {
matrunit(x,n);
scrmatr(x,n);
getchar();
}
}
}
else
return (x * power (x,n-1));
}
PROBLEME PROPUSE
P3.1 Functie pentru determinarea numarului de cifre al unui numar dat (de
orice tip intreg). Program pentru citirea unui intreg n si afisarea a n
numere aleatoare intre 0 si n, cu determinare numar de coloane in functie
de valorile afisate. ( nr de coloane = 80/(nr.cifre+2) )
Se va utiliza functia "random" declarata in <math.h>
P3.2 Functie care verifica daca un numar dat este prim sau nu. Program
pentru afisarea descompunerilor numerelor pare mai mici ca un intreg dat
in sume de doua numere prime (Ipoteza lui Goldbach = orice numar par se
poate scrie ca suma a doua numere prime).
P3.3 Functie care primeste doi intregi a si b si determina alti doi
intregi k si c astfel ca a = c * b^k ( b este un divizor posibil al lui a,
k este ordinul de multiplicitate, c este numarul ramas dupa k impartiri
repetate a lui a prin b). Program pentru descompunerea unui numar dat in
factori primi (cu puterile lor) folosind functia. Exemplu:
360 = 2^3 * 3^2 * 5^1
P3.4 Functie care determina pozitia valorii maxime intr-un vector. Program
pentru ordonarea unui vector de numere prin determinarea repetata a valorii
maxime dintr-un vector si schimbarea cu ultimul element din vector.
P3.5 Functie care determina semnul unui numar intreg ("sign") si are
rezultat 0 (valoare zero), -1 (numar negativ) sau +1 (numar pozitiv).
Functie care determina numarul cadranului in care se afla un punct de
coordonate intregi date x,y; rezultatul este 0 daca punctul se afla pe
una din axe sau la intersectia axelor. Indicatie: Se face o selectie
("switch") dupa valoarea 3*sign(x)+sign(y). Program de verificare.
P3.6 Functie pentru cautare binara intr-un vector ordonat in doua moduri:
iterativ si recursiv. Cautarea binara se face prin compararea valorii
cautate cu valoarea din mijlocul vectorului cercetat si alegerea primei
sau ultimei jumatati din vector pentru pasul urmator, in functie de
rezultatul comparatiei. Procesul de injumatatire a vectorului se opreste
fie la gasirea valorii cautate, fie la reducerea dimensiunii pana la 1.
Functia primeste ca argumente valoarea cautata, adresa vectorului si
indicii (pozitiile) din vector intre care se cauta.
return (int)log10(x) + 1 ;
}
// afisare vector de numere cu tabelare automata
void main () {
int x[10000]; int i,n,m,nv,max;
printf("n="); scanf("%d",&n);
max=0;
// completare vector de n intregi
for ( i=0;i<n;i++) {
x[i]=random(n);
m=digits (x[i]);
if ( max <m) max=m;
}
// printf ("nr. max. cifre=%d \n",max);
// afisare vector
nv=80/(max+1);
// nr. maxim de coloane
for ( i=0;i<n;i++) {
if (i%nv==0)
printf ("\n");
printf ("%*d",max+2,x[i]); // scrie x[i] pe max+2 pozitii
}
}
//
R3.2
// verifica daca este numar prim
int prim ( int n) {
int d;
for (d=2; d<=n/2 ; d++)
if ( n%d==0)
return 0;
// nu este prim
return 1;
// este prim
}
// verif. ipotezei lui Goldbach
main () {
int n,m,k;
printf("n="); scanf("%d",&n);
for (m=2; m<=n; m=m+2)
// incearca numerele k si m-k daca prime
for (k=1; k<=m/2; k++)
if (prim(k) && prim (m-k))
printf (" %d =%d+%d \n",m,k,m-k);
}
//
R3.3
// factorul de multiplicitate al lui b in a
im=imax(x,n);
// schimba x[im] cu x[n-1]
aux=x[im];
x[im]=x[n-1];
x[n-1]=aux;
n--;
// scade dimensiune vector
}
}
// verificare
void main () {
float t[]= {5,2,9,1,4,6,2,8};
int i, n = sizeof(t)/sizeof(t[0]);
sort (t,n);
for (i=0;i<n;i++)
printf ("%.2f ",t[i]);
}
//
R3.5
#include <stdio.h>
#include <math.h>
// semn numar algebric = -1 sau 1 sau 0
int sign (int x) {
if (x==0) return 0;
else return x/abs(x);
}
// determinare cadran
int cadran ( int x, int y) {
int k= 3*sign(x)+sign(y);
switch (k){
case -1: case 1: case 3: case -3: return 0;
case 4: return 1;
case -2: return 2;
case -4: return 3;
case 2 : return 4;
}
}
// verificare functii
void main () {
int x,y, c;
do {
printf("x,y : "); scanf("%d%d",&x,&y);
c= cadran(x,y);
if (c==0)
printf ("Pe una din axe \n");
else
// pe axe
//
R3.6
// cautare binara, nerecursiva
int caut(int b,int a[],int i,int j) {
int m;
while (i <= j ) {
m=(i+j)/2;
// mijloc vector
if (a[m]==b)
return m;
// pozitia unde a fost gasit
else
if (a[m] < b)
i=m+1;
else
j=m-1;
}
return -1;
}
// cautare binara, recursiva
int caut(int b,int a[],int i,int j) {
int m;
if ( i > j)
return -1; /* negsit */
else {
m=(i+j)/2;
if (a[m]==b)
return m;
else if (b < a[m])
return caut (b,a,i,m-1);
else
return caut (b,a,m+1,j);
}
}
//
R3.7
// operatii cu multimi de biti
#include <stdio.h>
#define DIM 16
typedef unsigned int Set[DIM];
// initializare multime vida
void init (Set m){
int i;
for(i=0;i<DIM;i++) m[i]=0;
}
// adauga la multimea m valoarea x
void add (Set m,int x){
int i,j;
i= x / 16;
j= x % 16;
m[i]= m[i] | (1<<j);
}
// reuniune de multimi ( c=a+b)
void or (Set a, Set b, Set c) {
int i;
for (i=0; i<DIM;i++)
c[i]=a[i] | b[i];
}
// intersectie de multimi (c=a&b)
void and (Set a, Set b, Set c) {
int i;
for (i=0; i<DIM;i++)
c[i]=a[i] & b[i];
}
// diferenta simetrica de multimi
void xor (Set a, Set b, Set c) {
int i;
for (i=0; i<DIM;i++)
c[i]=a[i] ^ b[i];
}
// diferenta de multimi (c=a-b)
void dif (Set a, Set b, Set c) {
Set t;
and (a,b,t);
xor (a,t,c);
}
// verifica aparteneta la multimea m a lui x
int is (Set m,int x){
int i,j;
i= x / 16;
j= x % 16;
return m[i] | (1<<j);
}
// afisarea multimii m
void print (Set m)
{ int j,i;
printf("{ ");
for(j=0;j<16;j++)
for (i=0;i<16;i++)
if(m[j] & (1<<i))
printf("%d,",i+16*j);
printf("\b }\n");
}
// verificarea unor functii
main() {
Set a,b,c,t,u,v;
int i;
init (a); init (b);
for (i=10;i<100;i=i+20)
add (a,i);
for (i=5;i<100;i+=15)
add(b,i);
or (a,b,c); print(c);
and (a,b,t); print (t);
xor (a,b,u); print (u);
dif (a,b,v); print (v);
}
//
R3.8
// operatii cu multimi reprezentate prin vectori neordonati
#include <stdio.h>
#define M 256
// dimensiune maxima vectori (multimi)
// initializare multime vida
void init (int a[]) {
int i;
for (i=0;i<M;i++)
a[i]=0;
}
// test daca o valoare data apartine unei multimi
int contine (int a[], int x) {
int i;
for (i=0; i<M && a[i] > 0 ; i++)
if (x==a[i])
return 1; // x apartine lui a
return 0;
// x nu apartine lui a
}
// dimensiunea (cardinalul) unei multimi
int dim (int a[]) {
int i, m=0;
for (i=0; i<M && a[i] > 0 ; i++)
m=m+1;
return m;
}
// adaugare element la o multime
int i,k;
init(c);
for (i=0; i<M && a[i];i++)
if ( ! contine (b, a[i]) ) // elem. din a care nu sunt si in b
plus (c,a[i]);
}
// comparatie la egalitate multimi
int egal (int a[], int b[]) {
int i;
if ( dim(a) != dim(b) )
return 0;
if (continem (a,b))
return 1;
else
return 0;
}
// citire multime vector
int citmul (int a[]) {
int i=0;
init (a);
do { scanf("%d", &a[i++]);
} while (a[i-1]);
return i;
}
// verificare functii
void main () {
int a[M], b[M], c[M], d[M], e[M], f[M], r[M];
citmul(a); citmul(b);
scrie(a); scrie(b);
plusm (a,b,c); scrie (c);
inters (a,b,d); scrie (d);
minusm(a,b,e); minusm (b,a,f);
plusm(d,e,r); plusm(r,f,r);
if ( egal (c,r) )
printf ("corect \n");
else
printf ("incorect \n");
}
//
R3.9
#include <stdio.h>
// calcul valoare polinom ptr un x dat
long valPol ( int c[], int n, int x) {
long s=0L; int i;
for (i=0;i<=n-1;i++)
s=s*x+c[i];
return s;
}
// vector cu divizorii unui intreg dat (pozitivi si negativi)
int div (int n, int d[]) {
int k,j=0;
if(n<0) n=-n;
// sa nu apara rest=-0 !
for (k=1; k<=n; k++)
if (n%k==0) {
d[j++]=k; d[j++]=-k; // k si -k sunt divizori
}
return j;
}
// impartire polinom prin x-r
void impPol (int a[],int n, int b[], int r) {
int k; --n;
b[0]=a[0];
for (k=1;k<=n-1;k++)
b[k]=a[k]+b[k-1]*r;
}
// radacini intregi ec. polinomiala
void main () {
int x, a[100],b[100], d[20],i=0, n, m, nr;
printf("nr. coef.="); scanf ("%d",&n);
printf ("coef. polinom,in ordinea descrescatoare a puterilor lui x:\n");
for (i=0;i<=n-1;i++)
scanf("%d",&a[i]);
printf ("Radacini intregi: ");
do {
// repeta cat e nevoie
m=div(a[n],d); // divizori termen liber
nr=0;
// numar de radacini intregi gasite
// verifica daca fiecare divizor este radacina
for (i=0;i<m;i++) {
if (valPol(a,n,d[i])==0) {
printf ("%d ",d[i]);
impPol (a,n,b,d[i]);
n--; ++nr;
for (i=0;i<n;i++)
a[i]=b[i];
// coef. noii ecuatii polinomiale (cu grad n-1)
}
}
} while (nr>0);
// scrie coeficienti polinom fara radacini intregi
// return ;
if (n >1) {
printf ("\nEcuatia fara coef. intregi: \n");
for (i=0;i<=n-1;i++)
if ( a[i])
printf ("%d(x^%d) ",a[i],n-1-i);
printf("\n");
}
}
//
R3.10
#include <stdio.h>
// Interpolare Lagrange
float lagrange ( float x[], float y[], int n, float xx) {
int i,k; float s=0,p;
for (k=1;k<=n;k++) {
p=1;
for (i=1;i<=n;i++)
if (i!=k)
p=p*(xx-x[i])/(x[k]-x[i]);
// aduna la suma
s=s+y[k]*p;
}
return s;
}
// program principal
void main () {
float x[100],y[100],xm[100],ym[100],xx,yy;
int n,i,j;
// citire date initiale
printf ("nr.puncte:"); scanf("%d",&n);
printf("coord. puncte:\n");
for (i=1;i<=n;i++) {
scanf ("%f%f",&xx,&yy);
x[i]=xx;y[i]=yy;
}
// creare vector de n-1 puncte prin interpolare
for (i=1;i<n;i++) {
xm[i]= (x[i]+x[i+1])/2;
ym[i]=lagrange(x,y,n,xm[i]);
}
for (i=1;i<=n-1;i++)
printf ("%f %f \n", xm[i],ym[i]);
}
//
R3.11
#include <stdio.h>
// produs dintre un polinom si un binom
// (a[n]+a[n-1]*x+...+a[0]*x^n)(x+c) = b[n+1]+b[n]*x+...+b[0]*x^(n+1)
int prodpoli (int a[], int n, int c, int b[]) {
int i;
b[0]=a[0];
for (i=1;i<n+1;i++)
b[i]=a[i]+a[i-1]*c;
b[n+1]=a[n]*c;
return n+1;
}
// calcul produs (x+c[0])*(x+c[1])* ...(x+c[n-1])=b[n]+b[n-1]*x+...+b[0]*x^n
void produs (int c[], int n, int b[]) {
int i,j,d[100];
b[0]=1;
for (i=0;i<n;i++) {
prodpoli (b,i,c[i],d);
for (j=0;j<=i+1;j++)
b[j]=d[j];
printf ("\n");
}
}
// verificare functii
void main () {
int a[100],b[100],i,j,n;
printf ("\n n="); scanf ("%d",&n);
for (i=0;i<n;i++)
scanf("%d",&a[i]);
produs (a,n,b);
printf (" Rezultate:\n");
for (i=0;i<=n;i++)
printf("%4d",b[i]);
}
//
R3.12
int cmmdc (int a,int b) {
if ( a%b==0)
return b;
return cmmdc( b,a%b);
}
//
R3.13
// recursiv
void binar (int n) {
if (n>0) {
binar (n/2);
printf("%d", n%2);
}
else
printf("0");
}
// iterativ (cu vector)
void binar2 ( int n) {
int c[16],i;
// aduna resturi in vector
i=0;
while ( n>0) {
c[i++]=n%2;
n=n/2;
}
printf ("%d\n",i);
// scrie vector in ordine inversa
while (i>0)
printf ("%d",c[--i]);
}
//
R3.14
// cautare secventiala recursiva intr-un vector
int lsearch (int a[], int n, int b) {
// cauta pe b in vectorul a de lungime n
if (n==0)
return -1;
// negasit
if (b==a[n-1])
return n-1;
// gasit in ultima pozitie
else
return lsearch(a,n-1,b); // cauta intr-un subvector mai mic
}
//
R3.15
#include <stdio.h>
#define M 20
typedef float num;
typedef num mat[M][M];
// generare matrice unitate
void matunit ( mat u,int n) {
int i,j;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
if (i ==j)
u[i][j]=1;
else
u[i][j]=0;
}
// dimensiuni matrice
// definire tip "mat"
//
R3.16
#include <stdio.h>
#define M 10
// nr maxim linii/coloane
typedef float mat[M][M];
// schimba intre ele doua linii dintr-o matrice patratica
void schimb ( mat a, int n, int i, int j) {
float aux;
int k;
for (k=1;k<=n;k++) {
aux=a[i][k];
a[i][k]=a[j][k];
a[j][k]=aux;
}
}
// aducere valori nenule pe diagonala unei matrice patratice
// rezultat 1 daca a reusit si 0 daca nu a reusit
int transf (mat a, int n) {
int i,j, gasit;
for (i=1;i<=n;i++)
// ptr fiecare linie i
if (a[i][i] == 0) {
gasit=0;
// cauta pe coloana i in liniile i+1,..n o val. nenula
for (j=1;j<=n;j++)
if ( j != i && a[j][i]) {
gasit=1; schimb (a,n,i,j);
}
if (gasit) continue;
else return 0;
}
return 1;
}
// verificare functie
void main () {
mat a; int i,j,n; float x;
printf ("n= "); scanf("%d",&n);
printf ("Elem matrice, pe linii: \n");
for (i=1;i<=n;i++)
for (j=1;j<=n;j++) {
scanf("%f",&x); a[i][j]=x;
}
i=transf (a,n);
// transforma matricea a
if (i==0) {
printf("Imposibil !\n");
return;
}
for (i=1;i<=n;i++) {
// scrie matricea transformata
for (j=1;j<=n;j++)
printf("%f ",a[i][j]);
printf("\n");
}
}
void main () {
char word[30]; // lungime maxima cuvant=30
while (scanf("%s",word) !=EOF)
printf("%s(%d)\n",word,strlen(word)); // un cuvant si lungimea sa
}
Obs.: Toate programele de mai sus pot fi folosite cu fisiere text de
intrare si de iesire prin redirectarea fisierelor standard stdin si stdout.
E4.4 Functie pentru insertia unui caracter la o adresa dintr-un sir.
Functie pentru insertia unui sir s la o adresa data din alt sir d.
// insertie caracter intr-un sir
void chins (char *d, char ch) {
char *p;
for (p=d+strlen(d); p>=d;p--)
* (p+1) = *p;
*d = ch;
}
// insertie sir s la adresa d
void strins (char *d, char *s) {
char *p; int ls=strlen(s);
for (p=s+ls-1; p >=s;p--)
chins(d,*p);
}
}
}
printf ("\n %d linii %d cuvinte",nl,nc);
fclose(f);
// nume fisiere
char line[200];
char *point ;
FILE * f1, * f2;
puts("Nume fisier text:"); gets(nume1);
if( (f1 = fopen (nume1,"r")) == NULL) {
printf(" fisier negasit \n"); return ;
}
strcpy(nume2,nume1);
point = strchr (nume2,'.');
if (point==0)
point=nume2+strlen(nume2);
strcpy(point+1,"$$$");
f2 =fopen (nume2,"w");
while ( fgets (line,200,f1) != 0)
fputs (line,f2);
if (fclose(f1)<0 || fclose(f2)<0) {
puts("Erori la fisiere \n"); return;
}
remove(nume1); rename(nume2,nume1);
}
PROBLEME PROPUSE
//
R4.2
// echivalenta cu "strncpy"
char * stcpy (char* d, char * s,int n) {
int i=0;
char * dd=d;
strcpy(aux,d);
strcpy(d,s);
strcat(d,aux);
}
// alta varianta de insertie sir s la adresa d
void strins (char *d, char *s) {
char * aux;
aux=strdup (d);
// duplicare d la adresa aux
strcpy(d,s);
strcpy (d+strlen(s), aux);
free(aux);
// eliberare memorie alocata de strdup
}
//
R4.4
// inlocuieste in txt toate apritiile lui s1 prin s2
void main () {
char txt[200] = "un bit plus un bit nu fac un byte";
char s1[]="un", s2[]="one";
char *p;
p=strstr (txt,s1);
// pozitia lui s1 n txt
while (p != NULL) {
strdel (p,strlen(s1)); // sterge pe s1 de la adresa p
strins(p,s2);
// insereaza s2 la adresa p
p=strstr(p+strlen(s2),s1);
// cauta alta aparitie a lui s1
}
puts (txt);
// afisare text dupa inlocuire
}
//
R4.5
// extragere subsiruri dintr-un sir (var.1)
void data (char * d, int r[3]) {
sscanf (d,"%d-%d-%d",&r[0],&r[1],&r[2]);
}
// extragere subsiruri dintr-un sir (var. 2)
void data (char *d, int r[]) {
char * sep="-";
r[0]=atoi (strtok(d,sep));
r[1]=atoi (strtok(0,sep));
r[2]=atoi (strtok(0,sep));
}
// verificare
void main () {
char d[]="25-12-1999";
int x[3];
data (d1,x);
//
R4.6
// afisare si numarare cuvinte
// (a) cu "strtok"
main () {
char *linie ="unu doi \ntrei patru \n cinci sase sapte opt";
char * token;
// adresa unui atom din text
char * sep=" \t\n";
int nt=0;
token= strtok (linie,sep);
while ( token != NULL) {
++nt;
printf ("%s \n", token);
token= strtok (0,sep);
}
printf ("%d atomi \n", nt);
}
// afisare si numarare cuvinte (atomi)
// (b) cu "sscanf"
main () {
char *linie ="unu doi \ntrei patru \n cinci sase
sapte opt";
char * p, token[40];
// un atom din text
int nt=0;
p=linie;
while ( sscanf(p,"%s",token) > 0) {
++nt;
printf ("%s \n", token);
p= strstr(linie,token)+strlen(token);
}
printf ("%d atomi \n", nt);
}
//
R4.7
char *strtok2 (char * sir,char *separ, char * tok) {
char *p, *r;
p=sir;
/* ignora separatori intre atomi */
while (strchr(separ,*p) && *p )
p++;
if (*p=='\0') return NULL;
r=p;
while (strchr(separ,*p)==NULL && *p)
p++;
R4.8
// extrage de la adresa adr un sir de litere la adresa rez
char * nextword ( char * adr, char * rez) {
while ( *adr && ! isalpha(*adr)) // ignora alte caractere
++adr;
while (*adr && isalpha(*adr))
// copiaza litere la adresa rez
*rez++=*adr++;
*rez=0;
// terminator sir rezultat
if (*adr==0)
return NULL;
// daca nu s-a gasit cuvant
else
return adr;
// adresa urmatoare cuvantului gasit
}
//
R4.9
// frecv de utilizare a unor cuvinte cheie
#include <stdio.h>
#include <string.h>
#include <ctype.h>
// cauta in tabel de cuv cheie
int keyw ( char * nume, char * kw[], int n ) {
int i;
for (i=0;i<n;i++)
if (strcmp(nume,kw[i])==0)
return i;
return -1;
}
// extrage de la adresa adr un cuvint la adresa rez
char * next ( char * adr, char * rez) {
while ( *adr && ! isalpha(*adr) )
++adr;
while (*adr && isalpha(*adr))
*rez++=*adr++;
*rez=0;
if (*adr==0)
return 0;
else
return adr;
// adresa urmatoare cuvantului gasit
}
void main () {
FILE * f; char buf[128] ;
char * p, *r, w[20];
char* kw [5]={"do","for","if","while","break","switch"};
int nr[5]={0};
// nr de aparitii ptr fiecare cuvint
int k,lc,n=5;
// lungime vectori kw si nr
printf ("nume fisier: "); scanf("%s",buf);
f=fopen (buf,"r");
if (f==NULL) {
printf("Fisierul %s nu exista \n",buf);
return;
}
while ( fgets(buf,128,f)!=0 ) {
p=buf;
while (r=next (p,w)) {
// lungime cuvant urmator
printf("%s ",w);
k= keyw (w,kw,n);
if (k >=0)
nr[k]++;
p=r;
// de aici continua cautarea
}
}
for (k=0;k<n;k++)
printf ("%8s = %d \n",kw[k],nr[k]);
}
//
R4.10
// compara doua siruri dupa cuvantul k din sir (k=0,1,..)
int compar ( char * a, char * b, int k) {
char w1[80], w2[80];
while (k>=0) {
sscanf(a,"%s",w1); sscanf(b,"%s",w2);
a=strstr(a,w1)+strlen(w1);
b=strstr(b,w2)+strlen(w2);
k=k-1;
}
return strcmp(w1,w2);
}
// ordonare linii din fisier text dupa orice cuvant din linie
void main ( int argc, char * argv[]) {
FILE * f;
char line[132]; int k,n, gata; char * aux;
char * tlin[1000];
// vector de pointeri la linii (max 1000)
f= fopen(argv[1],"r");
// nume fisier in argv[1]
int nc = atoi(argv[2]);
// numar cuvant in linie (0,1,..)
// citire fisier si creare vector de pointeri
k=0;
// k= indice in vectorul tlin
while ( fgets (line,132,f) )
tlin[k++]=strdup(line);
n=k;
// ordonare vector de pointeri
do {
gata =1;
for (k=0;k<n-1;k++)
if ( compar(tlin[k],tlin[k+1],nc) > 0) {
aux=tlin[k+1]; tlin[k+1]=tlin[k]; tlin[k]=aux;
gata=0;
}
} while (!gata);
// afisare fisier ordonat
puts("");
for (k=0;k<n;k++)
printf("%s",tlin[k]);
}
//
R4.11
typedef char word[30]; // un cuvint
// functie care cauta un sir intr-un vector de siruri
int caut ( word w, word t[], int n) {
int i;
for (i=0;i<n;i++)
if (strcmp(w,t[i])==0)
return i;
return -1;
}
// program principal
void main () {
#include <stdio.h>
typedef struct {
// o data calendaristica
int zi,luna,an;
} Date;
// comparare de date
int cmpdat ( Date d1, Date d2) {
int da,dl;
if ( da= (d1.an - d2.an)) return da;
// < 0 sau > 0
if ( dl= (d1.luna - d2.luna)) return dl;
return d1.zi-d2.zi;
// < 0, ==0, > 0
}
// ordonare vector de date
void sort (Date a[], int n) {
int i,j,gata; Date aux;
do {
gata=1;
for (i=0;i<n-1;i++)
if (cmpdat(a[i],a[i+1]) > 0 ) {
aux=a[i]; a[i]=a[i+1]; a[i+1]=aux;
gata=0;
}
} while ( ! gata);
}
// verificare
void main () {
Date d[30], dd; int n,i;
i=0;
while (scanf ("%d%d%d",&dd.zi,&dd.luna,&dd.an)!=EOF)
d[i++]=dd;
n=i;
sort(d,n);
for (i=0;i<n;i++)
printf("%d-%d-%d\n",d[i].zi,d[i].luna,d[i].an);
}
E5.4 Utilizare structuri pentru reducere numar de argumente la functii
// vectori reprezentati prin structuri
#include <stdio.h>
#define M 100
typedef struct sv {
int vec[M];
int dim;
} Vector;
// citire vector
Vector citvec ( ) {
};
typedef struct number Num;
// afisare numar
void write (Num n) {
switch (n.tipn) {
case 'I': printf ("%d ",n.v.ival);break;
case 'L': printf ("%ld ",n.v.lval);break;
case 'F': printf ("%f ",n.v.fval);break;
case 'D': printf ("%.15lf ",n.v.dval);break;
}
}
// citire numar
Num read (char tip) {
Num n;
n.tipn=tip;
switch (tip) {
case 'I': scanf ("%d", &n.v.ival);break;
case 'L': scanf ("%ld",&n.v.lval);break;
case 'F': scanf ("%f",&n.v.fval); break;
case 'D': scanf ("%lf",&n.v.dval); break;
}
return n;
}
// verificare functii
void main () {
Num a,b,c,d;
a = read('I'); b=read('L');
c = read('F'); d=read('D');
write(a); write(b); write(c); write(d);
}
Obs. Memorarea unor date de tipuri diferite la o aceeasi adresa se poate
realiza si fara tipul "union", folosind pointeri de tip "void *".
E5.6 Crearea si afisarea unui fisier de articole ce corespund unor structuri
din memorie (cu numele si mediile unor elevi).
// structura articole din fisier
typedef struct {
char nume[25];
float medie;
} Elev;
// creare - afisare fisier de articole
void main () {
FILE * f; Elev e;
char numef[80];
// aici se pune nume fisier
puts("Nume fisier:"); gets (numef);
// creare fisier
f=fopen(numef,"wb");
// creare de fisier binar
assert (f != NULL);
printf (" nume si medie ptr. fiecare student : \n\n");
while (scanf ("%s %f ",e.nume, &e.medie) != EOF)
fwrite(&e,sizeof(e),1,f);
fclose (f);
// listare fisier
f=fopen(numef,"rb");
// citire fisier binar
assert (f != NULL);
while (fread (&e,sizeof(e),1,f)==1)
printf ("%-25s %6.2f \n",e.nume, e.medie);
fclose (f);
}
PROBLEME PROPUSE
//
R5.1
// ... alte functii (citire, scriere, adunare)
// produs de numere complexe
void prod_cx (Complex a, Complex b, Complex* pc) {
Complex c;
c.re = a.re*b.re - a.im*b.im;
c.im = a.re*b.im + a.im*b.re;
*pc=c;
}
// ridicare complex la putere intreaga
void put_cx (Complex a, int n, Complex * pc) {
Complex c={1,0}; int k;
for (k=0;k<n;k++)
prod_cx (a,c, &c);
*pc=c;
}
// valoare polinom de variabila complexa
void pol_cx ( int n, Complex c[], Complex x, Complex* rez) {
int i; Complex sum=c[0], t;
for (i=1;i<=n;i++) {
put_cx(x,i,&t);
// t=x^i
prod_cx (c[i],t, &t); // c[i]*x^i
plus_cx (sum,t,&sum);
// aduna termen la suma
}
*rez=sum;
}
// verificare functii
void main () {
Complex a[30], x, c; int i,n;
printf("x="); cit_cx (&x);
printf("n="); scanf("%d",&n);
printf("Coeficienti: \n");
for (i=0;i<=n;i++)
cit_cx(&a[i]);
pol_cx(n,a,x,&c);
scr_cx(c);
}
//
R5.2
#include <stdio.h>
// operatii cu momente de timp
typedef struct {
int ora,min,sec;
} Time;
// verifica daca timp plauzibil
int corect (Time t) {
if ( t.ora < 0 || t.ora > 23 ) return 0;
if ( t.min < 0 || t.min > 59 ) return 0;
if ( t.sec < 0 || t.sec > 59 ) return 0;
return 1;
// plauzibil corect
}
// citire ora
Time rdtime () {
Time t;
do {
scanf ("%d%d%d", &t.ora, &t.min,&t.sec);
if ( ! corect (t))
printf ("Date gresite, repetati introducerea: \n");
else break;
} while (1);
return t;
}
// scrie ora
void wrtime ( Time t) {
printf ("%d:%d:%d \n", t.ora,t.min,t.sec);
}
// compara momente de timp
int cmptime (Time t1, Time t2) {
int h,m;
h=t1.ora-t2.ora;
m=t1.min-t2.min;
if (h) return h;
if (m) return m;
return t1.sec-t2.sec;
}
main () {
Time t1,t2;
do {
t1=rdtime(); wrtime(t1);
t2=rdtime(); wrtime(t2);
printf ("%d \n", cmptime(t1,t2));
} while (1);
}
//
R5.4
// structuri in probleme geometrice : punct, poligon etc.
#include <stdio.h>
#include <math.h>
typedef double Real;
typedef struct { Real x,y;} Punct;
typedef struct { int nv; Punct v[50];} Poligon;
// lungime segment delimitat de doua puncte
Real lung (Punct a, Punct b) {
Real dx= b.x-a.x;
Real dy= b.y-a.y;
return sqrt ( dx*dx+dy*dy);
}
// calcul primetru poligon
Real perim ( Poligon p) {
int i,n; Real rez=0;
n=p.nv;
for (i=0;i<n-1;i++)
rez = rez + lung (p.v[i],p.v[i+1]);
return rez+lung(p.v[n-1],p.v[0]);
}
// verificare
void main () {
Poligon p;
int i,n;
printf("nr. varfuri:"); scanf ("%d",&n);
p.nv=n;
printf ("coord. varfuri:\n");
for (i=0;i<n;i++)
scanf("%lf%lf", &(p.v[i].x), & (p.v[i].y) );
printf ("%lf \n", perim(p));
}
//
R5.5
#include <stdio.h>
#include <stdlib.h>
#define INCR 100
// cu cat creste vectorul
typedef int T;
// tip componente vector
typedef struct vf {
T * vec;
// adresa vector
int dim, dmax;
// dimensiune curenta si maxima
} Vector;
// initializare vector
void initVec (Vector * v) {
v->vec= (T *) malloc (INCR*sizeof(T));
v->dmax=INCR;
v->dim=0;
}
// adaugare element la vector
void addVec ( Vector * v, T x) {
if (v->dim == v->dmax) {
v->dmax += INCR;
/* extindere vector */
v->vec=(T*) realloc (v->vec, (v->dmax)*sizeof(T));
}
v->vec[v->dim]=x; v->dim ++;
}
// afisare vector
void printVec ( Vector v) {
void printT (T );
int i;
for (i=0; i< v.dim;i++)
printT ( v.vec[i]);
printf("\n");
}
// afisare valoare de tip T
void printT (T x) {
printf ("%d ",x);
}
// creare si afisare vector
void main() {
T x; Vector v;
initVec (&v);
while (scanf("%d",&x) != EOF)
addVec ( &v,x);
printVec (v);
}
//
R5.6
// frecventa de aparitie a cuvintelor, cu vector de structuri
#include <stdio.h>
#include <string.h>
#define MAXL 16 // nr maxim de litere dintr-un cuvant
#define MAXW 1000 // nr. maxim de cuvinte}
typedef struct {
char id[MAXL];
// cuvant
int na ;
// numar de aparitii
} Per;
// pereche cuvint-numar
typedef struct {
int nc;
// dimensiune vector
Per tc[MAXW] ; // tabel de cuvinte
} Dic;
void initDic (Dic * d) {
//
R5.7
// dictionar ca structura cu doi vectori
#include <stdio.h>
#include <string.h>
#define MAXL 16 // nr maxim de litere dintr-un cuvant
#define MAXW 1000 // nr. maxim de cuvinte
typedef struct {
int n;
// dimensiune vectori
char tc[MAXW][MAXL] ; // tabel de cuvinte
int tf[MAXW] ;
// tabel frecventa de aparitie
} Dic;
// initializare
void initDic (Dic * d) {
d->n=0;
}
// afisare dictionar
void printDic (Dic d) {
int i;
for (i=0;i< d.n;i++)
printf ("%20s %4d \n",d.tc[i], d.tf[i]);
}
// pune pereche cheie-valoare in dictionar
void putDic (Dic * d, char* cuv, int n) {
int i=0;
// cauta cheia in dictionar
while ( i<d->n && strcmp(cuv,d->tc[i]))
i++;
if (i >= d->n) {
//daca este un cuvint nou
strcpy (d->tc[d->n], cuv); // adauga la sfirsit de tabel
d->tf[d->n]=1;
// prima aparitie
++ d->n;
}
else
// cheie existenta
d->tf[i]=n;
}
// citire valoare asociata unei chei date
int getDic (Dic d, char * cuv) {
int i=0;
// cauta cheia in dictionar
while ( i< d.n && strcmp(cuv,d.tc[i]) )
i++;
if (i >= d.n)
//daca negasita
return -1;
else
return d.tf[i];
// frecventa cuv
}
// creare si afisare ductionar
void main () {
char word[MAXL]; // un cuvint
int nr;
// nr de aparitii
Dic dic; // lista de cuvine
initDic ( &dic);
while (scanf ("%s",word) > 0)
if ( (nr=getDic (dic,word)) >=0 )
// daca exista cuvantul
putDic (&dic,word,nr+1);
// mareste contor aparitii
else
putDic (&dic,word,1);
// daca nu exista
printDic (dic);
}
//
#include <stdio.h>
#include <stdlib.h>
#define M 10
typedef struct set {
int * val;
int max, n;
} * Set;
R5.8
//
#include <stdio.h>
#include <assert.h>
#include <string.h>
// structura articole fisier
R5.10
typedef struct {
char nume[20];
int cant; long val;
} Bon;
// adaugare bonuri la sfarsit de fisier (si creare fisier)
void adaugare (char * numef) {
FILE * f; Bon b; char c;
f=fopen (numef,"rb");
if (f==NULL) {
printf ("Fisier inexistent . Creare fisier nou ? (d/n) ");
fflush(stdin); c=getchar();
if (c=='n' || c=='N')
return;
f=fopen(numef,"wb"); assert (f != NULL);
}
else
f=fopen (numef,"ab"); // pozitionare pe afarsit de fisier
puts ("Introducere bonuri si creare fisier \n");
printf (" nume, cantitate, valoare : \n\n");
while (scanf ("%s %d %ld ",b.nume, &b.cant, &b.val) != EOF)
fwrite(&b,sizeof(b),1,f);
fclose (f);
}
// afisarea tuturor bonurilor din fisier
void listare (char* numef) {
FILE * f; Bon b;
f=fopen(numef,"rb"); assert (f != NULL);
while (fread (&b,sizeof(b),1,f)==1)
printf ("%-20s %6d %12ld \n",b.nume, b.cant, b.val);
fclose (f);
}
// afisare si totalizare bonuri pentru un produs dat
void total (char * numef) {
FILE * f; Bon b;
char numep[20]; long sum=0;
f=fopen(numef,"rb"); assert (f != NULL);
puts("\n\n\n"); fflush(stdin);
printf("Nume produs: "); gets(numep);
while (fread (&b,sizeof(b),1,f)==1)
if (strcmp(numep,b.nume)==0) {
printf ("%-20s %6d %12ld \n",b.nume, b.cant, b.val);
sum =sum+ b.val;
}
printf (" Valoare totala = %ld\n", sum);
fclose (f);
}
char s[80], * d;
do {
if (gets(s)==0) break;
d= strdup(s);
puts(d);
} while (1);
}
E6.2 Vector alocat dinamic (cu dimensiune cunoscuta la eexecutie)
#include <stdio.h>
#include <stdlib.h>
void main () {
int n,i;
int * a;
// adresa vector
printf("n="); scanf("%d",&n);
// dimensiune vector
a=(int*) malloc (n*sizeof(int));
printf("componente vector: \n");
for (i=0;i<n;i++)
// citire vector
scanf("%d", &a[i]);
for (i=0;i<n;i++)
// afisare vector
printf("%d ", a[i]);
}
E6.3 Vector realocat dinamic (cu dimensiune necunoscuta)
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define INCR 4
void main() {
int n,i,m ;
float x, * v;
n=INCR; i=0;
v=(float *)malloc (n*sizeof(float));
while (scanf("%f",&x) !=EOF){
if (i == n) {
n= n+ INCR;
v=(float *) realloc (v,n*sizeof(float));
}
v[i++]=x;
}
m=i;
for (i=0;i<m;i++)
printf ("%.2f ",v[i]);
}
tmp=vp[i]; vp[i]=vp[i+1];
vp[i+1]=tmp;
}
}
// citire siruri si creare vector de pointeri
int readstr (char * vp[]) {
int n=0; char * p, sir[80];
while ( scanf ("%s", sir) == 1) {
p= (char*) malloc (strlen(sir)+1);
strcpy( p,sir);
vp[n]=p; ++n;
}
return n;
}
void main () {
int n; char * vp[1000];
// vector de pointeri, cu dimens. fixa
n=readstr(vp);
// citire siruri si creare vector
sort ( vp,n);
// ordonare vector
printstr (vp,n);
// afisare siruri
}
E6.6 Structuri alocate dinamic si legate prin pointeri (liste inlantuite)
// creare si afisare lista simplu inlantuita
#include <stdio.h>
#include <stdlib.h>
// definire tip nod de lista
typedef struct snod {
int val;
// valoare nod
struct snod * leg;
// legatura la nodul urmator
} nod;
void main () {
nod * list, *nou, *p;
// lst = adresa primului nod
int x;
// citire numere si creare lista
list=NULL;
// lista initial vida
while (scanf ("%d",&x) > 0) {
nou= (nod*) malloc(sizeof(nod));
// creare nod nou
nou->val=x;
nou->leg=list; list=nou;
// adauga noul nod la inceputul listei
}
// afisare lista
p=list;
while ( p != NULL) {
// cat timp mai sunt noduri in lista
PROBLEME PROPUSE
b3[0]=l3;
// poate mai creste cu 1 !
for (i=1;i<=l3;i++) {
c1= i<=l1? b1[i]:0;
c2= i<=l2? b2[i]:0;
s=c1+c2+t;
t=s/10;
// transport la rangul urmator
s=s%10; b3[i]=s;
}
if (t) {
// transport de la ultimul rang;
b3[0]++;
b3[i]=1;
}
return b3;
}
// verificare functii
void main () {
char s[255],r[255]; bcd b1,b2,b3;
int i;
do {
scanf("%s",s);
b1=asc_bcd(s);
scanf("%s",s);
b2=asc_bcd(s);
b3=add_bcd (b1,b2);
bcd_asc (b3,r);
printf("%s\n",r);
} while (1);
}