Professional Documents
Culture Documents
Exerciţiul 1
Să se determine dacă un număr introdus de la tastatură este număr prim sau nu.
Soluţie Condiţia suficientă ca un număr n să fie prim este ca acesta să nu se dividă cu nici un alt număr din
intervalul 1..[ n ].
program nr_prim;
uses crt;
var
n:word;
a:real;
i,m:word;
prim:boolean;
begin
clrscr;
write('Introduceti numarul pentru test ');
readln(n);
prim:=true;
a:=n;
m:=trunc(sqrt(a));
i:=2;
while(i<=m) and prim do
if (n mod i) = 0 then prim:=false
else i:=i+1;
if prim then writeln('Numarul este prim')
else writeln('Numarul nu este prim');
readln;
end.
Exerciţiul 2
program polinoame;
uses crt;
var
p1,p2,suma,produs:array[0..40] of integer;
i,j,grad1,grad2,grad: integer;
1
procedure sumapol;
var k:integer;
begin
for k:=0 to grad do
suma[k]:=p1[k]+p2[k]
end;
procedure produspol;
var k,l,prod:integer;
begin
for k:=0 to grad1+grad2 do
begin
prod:=0;
for l:=0 to k do
prod:=prod+p1[l]*p2[k-l];
produs[k]:=prod
end
end;
{programul principal}
begin
clrscr;
write('Dati gradul maxim al polonmului1 '); readln(grad1);
write('Dati coeficientii primului polinom ');
for i:=0 to grad1 do readln(p1[i]);
write('Dati gradul maxim al celui de-al doilea polinom'); readln(grad2);
write('Dati coeficientii celui de-al doilea polinom ');
for i:=0 to grad2 do read(p2[i]);
if grad1>grad2 then grad:= grad1
else grad:=grad2;
sumapol;
produspol;
writeln('Suma polinoamelor este: ');
for i:=0 to grad-1 do
if( suma[i+1]>=0)then write(suma[i],'*X^',i,'+')
else write(suma[i],'*X^',i);
writeln(suma[grad],'*X^',grad);
writeln('Produsul polinoamelor este: ');
for i:=0 to grad1+grad2-1 do
if( produs[i+1]>=0)then write(produs[i],'*X^',i,'+')
else write(produs[i],'*X^',i);
writeln(produs[grad1+grad2],'*X^',grad1+grad2);
end.
Exerciţiul 3
Să se genereze toate permutările mulţimii {1, 2,..., n}, unde n este un număr natural citit de la
tastatură, n ≤ 7.
Soluţie: Problema va fi rezolvată utilizându-se metoda backtracking. Forma standard a acestei metode se
aplică problemelor în care trebuie găsit un vector x=(x1, x2, ..., xn) din spaţiul soluţiilor S=S1× S2× ...× Sn
2
unde, pentru orice 1≤ i ≤ n, Si = si (număr finit de elemente) şi pe Si este definită o relaţie de ordine, iar
x reprezintă soluţia rezultat satisfăcând condiţiile interne corespunzătoare problemei. Ca variante de ieşiri
sunt posibile cazurile: o singură soluţie rezultat, toate soluţiile rezultat (în probleme de generare
asemănătoare celei propuse), o soluţie rezultat care optimizează (minim sau maxim) un criteriu f:S→R.
Construcţia unei soluţii se face astfel:
• se presupun determinate la momentul curent x1, x2, ..., xk;
• dacă secvenţa anterior calculată satisface condiţiile de continuare specifice problemei (dacă
există şansa de a se obţine o soluţie rezultat) se alege xk+1 ∈ Sk+1
• altfel, dacă xk are succesor în Sk, xk ← succ(xk)
• altfel, dacă xk nu are succesor în Sk, se procedează în aceeaşi manieră cu “resatisfacerea” lui xk-
1.
Procedura generală de calcul este următoarea:
procedure back(k:byte);
begin
if k=n+1 then final
else
begin
x[k]:=init(k);
while succ(k) do
if continuare(k) then back(k+1);
end;
end;
în care:
• final este o procedură specifică momentului în care s-a determinat o soluţie rezultat x (se
afişează rezultatul, se testează o funcţie criteriu pentru soluţia obţinută, aceasta selectându-se doar în anumite
condiţii de optim samd);
• init(k) este o funcţie de iniţializare a lui xk cu predecesorulu primului element din Sk;
• succ(k) este o funcţie booleană care testează existenţa succesorului lui xk în Sk şi dacă acest
lucru este posibil se înlocuieşte xk cu succesorul lui din Sk;
• continuare(k) este o funcţie booleană care testează condiţiile de continuare (dacă secvenţa
determinată până la momentul curent poate duce la o soluţie rezultat).
În continuare este prezentată problema generării tuturor permutărilor mulţimii {1, 2,..., n} aplicându-
se exact metoda generală şi ţinându-se cont de următoarele aspecte:
• S1 = S2 = ... = Sn = {1, 2,..., n} (deci funcţia init nu depinde de nici un parametru, întorcând
valoarea 0 indiferent de indicele elementului de iniţializat);
• condiţia ca secvenţa {x1, x2,..., xk} să fie una corectă pentru a se iniţia generarea lui xk+1 (ştiind
că {x1, x2,..., xk-1} este corectă) este cea dată de definiţia unei permutări: xk ∉ {x1, x2,..., xk-1}.
function init:byte;
begin
init:=0;
end;
3
function succ(k:byte):boolean;
begin
succ:=x[k]<n; inc(x[k]);
end;
function continuare(k:byte):boolean;
var i:byte;
begin
i:=1;
while(i<k)and(x[i]<>x[k]) do inc(i);
continuare:=i=k;
end;
procedure final;
var i:byte;
begin
for i:=1 to n do write(x[i],' ');
readln;
end;
procedure back(k:byte);
begin
if k=n+1 then final
else
begin
x[k]:=init;
while succ(k) do
if continuare(k) then back(k+1);
end;
end;
begin
clrscr;
write('Numarul de elemente al permutarii: ');
readln(n);
back(1);
end.
După cum se poate remarca, unele din opera]iile precedente (cum ar fi funcţia init, lucrul cu funcţia
succ în condiţiile în care S1 = S2 = ... =Sn = {1, 2,..., n}) pot fi reformulate într-o manieră ce simplifică
scrierea programului. De exemplu, o altă variantă corectă de rezolvare este:
program permutare_1;
uses crt;
type tip_elem=0..7;
var x:array[1..7] of tip_elem;
n:byte;
procedure final;
4
var i:byte;
begin
for i:=1 to n do write(x[i],' ');
readln;
end;
function continuare(k:byte):boolean;
var i:byte;
begin
i:=1;
while(i<k)and(x[i]<>x[k]) do inc(i);
continuare:=i=k;
end;
procedure back(k:byte);
var i:byte;
begin
if k=n+1 then final
else
for i:=1 to n do
begin
x[k]:=i;
if continuare(k) then back(k+1);
end;
end;
begin
clrscr;
write('Numarul de elemente al permutarii: ');
readln(n);
back(1);
end.
Problema 5 Să se scrie programul Pascal pentru generarea tuturor submulţimilor mulţimii {1, 2,...,
n}, unde n este un număr natural citit de la tastatură, n ≤ 10.
0 ,S ∉ [ S i ]u b S
S u =b S [ i ]
1, S ∈ [ S i ]u b S
Condiţiile de continuare sunt cele ce caracterizează o submulţime a unei mulţimi, momentul
terminării generării unei soluţii - o submulţime cu k elemente - sesizându-se când suma elementelor
vectorului generat este k. În momentul determinării unei submulţimi, aceasta este trecută într-un vector,
generându-se astfel P({1, 2,..., n}).
5
program submultime;
type elem=0..1;
sub=array[1..10] of elem;
var
n,dim:byte;
x:sub;
tot:array[1..200] of sub;
k,j:integer;
nr:byte;
function suma(t,k:byte):boolean;
var
s,i:byte;
begin
s:=0;
for i:=1 to t do s:=s+x[i];
if s<=k then suma:=true
else suma:=false;
end;
function sumaf:byte;
var
s,i:byte;
begin
s:=0;
for i:=1 to n do s:=s+x[i];
sumaf:=s;
end;
procedure back(k,t:byte);
var
i:byte;
begin
if (t=n+1) then
if(sumaf=k) then
begin
inc(nr);
for i:=1 to n do tot[nr][i]:=x[i];
end
else
else
for i:=2 downto 1 do
begin
x[t]:=i-1;
if suma(t,k) then back(k,t+1);
end;
end;
6
begin
readln(n);
nr:=0;
for dim:=1 to n do back(dim,1);
writeln('Submultimile sunt:');
for k:=1 to nr do
begin
for j:=1 to n do
if tot[k][j]=1 then write(j,' ');
writeln;
end;
end.
Soluţie Fie X un vector aleator cu medie µ şi matrice de covarianţă Σ , {X1, X2,..., Xm} o selecţie
bernoulliană de volum m asupra lui X.
1 m
• media de selecţie se calculează astfel: µ =
m i=1∑Xi ;
• cum matricea de covarianţă de selecţie este simetrică şi pozitiv definită, rezultă că se poate
aplica algoritmul lui Jacobi [citarea algoritmului]; valorile proprii vor fi reale, pozitive, iar vectorii proprii
vor avea cu componente reale.
Unit-ul complet este:
unit stat;
interface
type vect_ra=array[1..30] of real;
selectie=array[1..50] of vect_ra;
matrice=array[1..30,1..30] of real;
procedure media(var s:selectie; var med:vect_ra;dim_v,vol_sel:byte);
procedure covarianta(var s:selectie;var sigma:matrice;dim_v,vol_sel:byte);
procedure autocorelatie(var s:selectie;var auto:matrice;dim_v,vol_sel:byte);
procedure vect_val_pr(var sel:selectie;var val_pr:vect_ra; var vect_pr: matrice;
dim_v, vol_sel:byte; eps:real; itmax:word);
7
implementation
procedure media;
var
i,j:byte;
begin
for i:=1 to dim_v do
begin
med[i]:=0;
for j:=1 to vol_sel do
med[i]:=med[i]+s[j][i];
med[i]:=med[i]/vol_sel;
end;
end;
procedure covarianta;
var
i,j,k:byte;
medie:vect_ra;
begin
media(s,medie,dim_v,vol_sel);
for i:=1 to dim_v do
for j:=1 to dim_v do
begin
sigma[i,j]:=0;
for k:=1 to vol_sel do
sigma[i,j]:=sigma[i,j]+(s[k][i]-medie[i])*(s[k][j]-medie[j]);
sigma[i][j]:=sigma[i,j]/(vol_sel-1);
end;
end;
procedure autocorelatie;
var
i,j,k:byte;
begin
for i:=1 to dim_v do
for j:=1 to dim_v do
begin
auto[i,j]:=0;
for k:=1 to vol_sel do
auto[i,j]:=auto[i,j]+s[k][i]*s[k][j];
auto[i][j]:=auto[i,j]/vol_sel;
end;
end;
procedure vect_val_pr;
var
i,it,j,k:byte;
aii,aji,ajj,amax,c,c1,s,t,inter,inter1:real;
8
sigma:matrice;
begin
it:=0;
covarianta(sel,sigma,dim_v,vol_sel);
for i:=1 to dim_v do
begin
for j:=1 to dim_v do
vect_pr[i][j]:=0;
vect_pr[i][i]:=1;
val_pr[i]:=sigma[i,i];
end;
amax:=1;
while((amax>eps)and(it<itmax)) do
begin
inc(it);amax:=0;
for j:=2 to dim_v do
for i:=1 to j-1 do
begin
aii:=val_pr[i];ajj:=val_pr[j];
aji:=abs(sigma[j,i]);
if(amax<aji) then amax:=aji;
if(aji>eps) then
begin
c:=0.5*(aii-ajj)/sigma[j,i];
t:=1/(abs(c)+sqrt(1+c*c));
if c<0 then t:=-t;
c:=1/sqrt(1+t*t);s:=c*t;
for k:=1 to i-1 do
begin
t:=sigma[i,k]*c+sigma[j,k]*s;
sigma[j,k]:=sigma[j,k]*c-sigma[i,k]*s;
sigma[i,k]:=t;
end;
for k:=i+1 to j-1 do
begin
t:=sigma[k,i]*c+sigma[j,k]*s;
sigma[j,k]:=sigma[j,k]*c-sigma[k,i]*s;
sigma[k,i]:=t;
end;
for k:=j+1 to dim_v do
begin
t:=sigma[k,i]*c+sigma[k,j]*s;
sigma[k,j]:=sigma[k,j]*c-sigma[k,i]*s;
sigma[k,i]:=t;
end;
for k:=1 to dim_v do
begin
t:=vect_pr[k,i]*c+vect_pr[k,j]*s;
9
vect_pr[k,j]:=vect_pr[k,j]*c-vect_pr[k,i]*s;
vect_pr[k,i]:=t;
end;
t:=2*s*c*sigma[j,i];
val_pr[i]:=aii*c*c+ajj*s*s+t;
val_pr[j]:=aii*s*s+ajj*c*c-t;
sigma[j,i]:=0;
end;
end;
end;
for i:=1 to dim_v-1 do
for j:=i+1 to dim_v do
if(val_pr[i]<val_pr[j]) then
begin
inter:=val_pr[i];val_pr[i]:=val_pr[j];val_pr[j]:=inter;
for k:=1 to dim_v do
begin
inter1:=vect_pr[k,i];
vect_pr[k,i]:=vect_pr[k,j];
vect_pr[k,j]:=inter1;
end;
end;
end;
end.
Probleme propuse
1. Să se scrie programul Pascal pentru determinarea celui mai mic multiplu comun al două numere.
2. Să se scrie un subprogram Pascal pentru a decide dacă două numere naturale sunt prime între ele.
3. Să se scrie programul Pascal pentru generarea tuturor numerelor prime mai mici decât n, n citit de
la tastatură.
4. Să se scrie un subprogram Pascal pentru calculul celui mai mare divizor comun a n numere
naturale, n≥ 3.
5. Să se scrie un subprogram Pascal pentru descompunerea unui număr natural în factori primi.
6. Să se scrie programul Pascal pentru generarea tuturor combinărilor de k elemente ale unei mulţimi
de n elemente, n≥ k.
7. Să se scrie un subprogram Pascal pentru calculul valorii unui polinom într-un punct dat.
8. Să se scrie un subprogram Pascal pentru calculul derivatei unui polinom.
9. Să se scrie un subprogram Pascal pentru determinarea compunerii a două polinoa-me.
10. Utilizând algoritmul lui Euclid, să se scrie subprogramele Pascal pentru determinarea celui mai
mare divizor comun şi a celui mai mic multiplu comun pentru două polinoame.
11. Să se realizeze programul Pascal pentru calculul polinomului de interpolare Lagrange pentru un
set de perechi {(x1, y1 ), (x2, y2), …, (xn, yn)} citite de la tastatură.
10
program gaussexp;
uses crt;
var csi,o,z,z0:real;
i:integer;
begin
clrscr;
randomize;
for i:=1 to 100 do
begin
readln(o);
norm01(z0);
norm01(csi);
z:=o*z0+sqrt(1-o*o)*csi;
writeln(z);
end;
end.
{**** Acest program va genera procesul gaussian cu functie de autocorelatie liniara folosind
algoritmul clasic ****} program gauss;
uses crt;
var v:array[1..100] of real;
x,a:real;
i,n,p:integer;
begin
clrscr;
randomize;
readln(a,n,p);
for i:=1 to n do v[i]:=random;
for i:=1 to n-p do v[i]:=v[i+p];
x:=0;
for i:=1 to n-p do
x:=x+v[i];
for i:=1 to p do
v[n-p+i]:=-a+2*a*random;
11
for i:=n-p+1 to n do
x:=x+v[i];
for i:=1 to n do write(' ',v[i]);
end.
program gener;
uses crt;
var
f1:text;
q,u1,v:real;
i,n,j,l:integer;
function fp(m:real):integer;
var
u,s,p:real;
k:integer;
begin
k:=0;p:=exp(-m);
u:=random;
s:=p;
while u>s do begin
k:=k+1;
p:=p*m/k;
s:=s+p;
end;
fp:=k;
end;
begin
writeln('Dati q ');
readln(q);
writeln('Dati numarul generarilor ');
readln(l);
assign(f1,'as.txt');
rewrite(f1);
randomize;
for j:=1 to l do begin
n:=fp(q*3.14);
writeln(n);
for i:=1 to n do begin
repeat
u1:=2*random-1;
v:=2*random-1;
until u1*u1+v*v<=1;
writeln(f1,' ',u1,' ',v);
12
end;
end;
close(f1);
writeln;
end.
{**** Acest program genereaza numere aleatoare conform algoritmului
clasic Gsalca cu repartitia de intrare exponentiala avand
cealalta functie de intrare cea data de functia fct de mai jos
****}
program Gslaca;
uses crt;
var x,y,s:real;
z:array[1..2] of real;
i:integer;
13
uses crt;
var
a,b:real;
F,P:array[1..2,1..2] of real;
i,j,k:integer;
suma,U:real;
begin
clrscr;
readln(a);
readln(b);
if((a>=1)or(a<=0)or(b>=1)or(b<=0)) then begin
writeln('Date incorecte!');
exit;
end;
P[1,1]:=a;P[1,2]:=1-a;
P[2,1]:=1-b;P[2,2]:=b;
for i:=1 to 2 do begin
suma:=0;
for j:=1 to 2 do begin
for k:=1 to j do
suma:=suma+P[i,k];
F[i,j]:=suma;
end;
end;
j:=1;
randomize;
U:=random;
i:=1;
while (F[i,j]<=U) do j:=j+1;
writeln('S-a generat starea ',j-1);
end.
program poisson1;
{***** Acest program genereaza un proces Poisson 1-dimensional
omogen pe segmentul (0,x0] *****}
uses crt;
var
l,x0,x:real;
n:integer;
begin
clrscr;
randomize;
readln(l,x0);
x:=0;n:=0;
while x<=x0 do
14
begin
x:=x-(1/l)*ln(1-random);
n:=n+1;
writeln(x,' ',n);
end;
end.
program poisson2;
uses crt;
var
l,x0,x,y0,y:real;
n:integer;
begin
clrscr;
randomize;
readln(l,x0,y0);
x:=0;n:=0;
while x<=x0 do
begin
x:=x-(1/l)*ln(1-random);
y:=random*y0;
n:=n+1;
writeln(x,' ',y,' ',n);
end;
end.
15
EXERCIŢII DIVERSE
Exerciţiul 1
program nr_prim;
uses crt;
var
n:word;
a:real;
i,m:word;
prim:boolean;
begin
clrscr;
write('Introduceti numarul pentru test ');
readln(n);
prim:=true;
a:=n;
m:=trunc(sqrt(a));
i:=2;
while(i<=m) and prim do
if (n mod i) = 0 then prim:=false
else i:=i+1;
if prim then writeln('Numarul este prim')
else writeln('Numarul nu este prim');
readln;
end.
Exerciţiul 2
program polinoame;
uses crt;
var
p1,p2,suma,produs:array[0..40] of integer;
i,j,grad1,grad2,grad: integer;
procedure sumapol;
var k:integer;
begin
for k:=0 to grad do
16
suma[k]:=p1[k]+p2[k]
end;
procedure produspol;
var k,l,prod:integer;
begin
for k:=0 to grad1+grad2 do
begin
prod:=0;
for l:=0 to k do
prod:=prod+p1[l]*p2[k-l];
produs[k]:=prod
end
end;
{programul principal}
begin
clrscr;
write('Dati gradul maxim al polonmului1 '); readln(grad1);
write('Dati coeficientii primului polinom ');
for i:=0 to grad1 do readln(p1[i]);
write('Dati gradul maxim al celui de-al doilea polinom'); readln(grad2);
write('Dati coeficientii celui de-al doilea polinom ');
for i:=0 to grad2 do read(p2[i]);
if grad1>grad2 then grad:= grad1
else grad:=grad2;
sumapol;
produspol;
writeln('Suma polinoamelor este: ');
for i:=0 to grad-1 do
if( suma[i+1]>=0)then write(suma[i],'*X^',i,'+')
else write(suma[i],'*X^',i);
writeln(suma[grad],'*X^',grad);
writeln('Produsul polinoamelor este: ');
for i:=0 to grad1+grad2-1 do
if( produs[i+1]>=0)then write(produs[i],'*X^',i,'+')
else write(produs[i],'*X^',i);
writeln(produs[grad1+grad2],'*X^',grad1+grad2);
end.
Exerciţiul 3
Să se genereze toate permutările mulţimii {1, 2,..., n}, unde n este un număr natural citit de la
tastatură, n ≤ 7.
Soluţie: Problema va fi rezolvată utilizându-se metoda backtracking. Forma standard a acestei metode se
aplică problemelor în care trebuie găsit un vector x=(x1, x2, ..., xn) din spaţiul soluţiilor S=S1× S2× ...× Sn
unde, pentru orice 1≤ i ≤ n, Si = si (număr finit de elemente) şi pe Si este definită o relaţie de ordine, iar
x reprezintă soluţia rezultat satisfăcând condiţiile interne corespunzătoare problemei. Ca variante de ieşiri
sunt posibile cazurile: o singură soluţie rezultat, toate soluţiile rezultat (în probleme de generare
asemănătoare celei propuse), o soluţie rezultat care optimizează (minim sau maxim) un criteriu f:S→R.
Construcţia unei soluţii se face astfel:
• se presupun determinate la momentul curent x1, x2, ..., xk;
• dacă secvenţa anterior calculată satisface condiţiile de continuare specifice problemei (dacă
există şansa de a se obţine o soluţie rezultat) se alege xk+1 ∈ Sk+1
17
• altfel, dacă xk are succesor în Sk, xk ← succ(xk)
• altfel, dacă xk nu are succesor în Sk, se procedează în aceeaşi manieră cu “resatisfacerea” lui xk-
1.
Procedura generală de calcul este următoarea:
procedure back(k:byte);
begin
if k=n+1 then final
else
begin
x[k]:=init(k);
while succ(k) do
if continuare(k) then back(k+1);
end;
end;
în care:
• final este o procedură specifică momentului în care s-a determinat o soluţie rezultat x (se
afişează rezultatul, se testează o funcţie criteriu pentru soluţia obţinută, aceasta selectându-se doar în anumite
condiţii de optim ş.a.m.d.);
• init(k) este o funcţie de iniţializare a lui xk cu predecesorulu primului element din Sk;
• succ(k) este o funcţie booleană care testează existenţa succesorului lui x k în Sk şi, dacă acest
lucru este posibil, se înlocuieşte xk cu succesorul lui din Sk;
• continuare(k) este o funcţie booleană care testează condiţiile de continuare (dacă secvenţa
determinată până la momentul curent poate duce la o soluţie rezultat).
În continuare este prezentată problema generării tuturor permutărilor mulţimii {1, 2,..., n} aplicându-
se exact metoda generală şi ţinându-se cont de următoarele aspecte:
• S1 = S2 = ... = Sn = {1, 2,..., n} (deci funcţia init nu depinde de nici un parametru, întorcând
valoarea 0 indiferent de indicele elementului de iniţializat);
• condiţia ca secvenţa {x1, x2,..., xk} să fie una corectă pentru a se iniţia generarea lui xk+1 (ştiind
că {x1, x2,..., xk-1} este corectă) este cea dată de definiţia unei permutări: xk ∉ {x1, x2,..., xk-1}.
function init:byte;
begin
init:=0;
end;
function succ(k:byte):boolean;
begin
succ:=x[k]<n; inc(x[k]);
end;
function continuare(k:byte):boolean;
var i:byte;
begin
i:=1;
18
while(i<k)and(x[i]<>x[k]) do inc(i);
continuare:=i=k;
end;
procedure final;
var i:byte;
begin
for i:=1 to n do write(x[i],' ');
readln;
end;
procedure back(k:byte);
begin
if k=n+1 then final
else
begin
x[k]:=init;
while succ(k) do
if continuare(k) then back(k+1);
end;
end;
begin
clrscr;
write('Numarul de elemente al permutarii: ');
readln(n);
back(1);
end.
După cum se poate remarca, unele din operaţiile precedente (cum ar fi funcţia init, lucrul cu funcţia
succ în condiţiile în care S1 = S2 = ... =Sn = {1, 2,..., n}) pot fi reformulate într-o manieră ce simplifică
scrierea programului. De exemplu, o altă variantă corectă de rezolvare este:
program permutare_1;
uses crt;
type tip_elem=0..7;
var x:array[1..7] of tip_elem;
n:byte;
procedure final;
var i:byte;
begin
for i:=1 to n do write(x[i],' ');
readln;
end;
function continuare(k:byte):boolean;
var i:byte;
begin
i:=1;
while(i<k)and(x[i]<>x[k]) do inc(i);
continuare:=i=k;
end;
procedure back(k:byte);
19
var i:byte;
begin
if k=n+1 then final
else
for i:=1 to n do
begin
x[k]:=i;
if continuare(k) then back(k+1);
end;
end;
begin
clrscr;
write('Numarul de elemente al permutarii: ');
readln(n);
back(1);
end.
Exerciţiul 4
Să se scrie programul Pascal pentru generarea tuturor submulţimilor mulţimii {1, 2,..., n}, unde n
este un număr natural citit de la tastatură, n ≤ 10.
Soluţie: Se vor genera, prin metoda backtracking, toate submulţimile cu k elemente, 1 ≤ k ≤ n. Modul de
reprezentare a unei submulţimi SubS a lui S (privite ca vectori) este:
SubS[ i ] =
0, S [i ]∉SubS
1, S [i ]∈SubS
¿
¿ {¿ ¿¿
Condiţiile de continuare sunt cele ce caracterizează o submulţime a unei mulţimi, momentul
terminării generării unei soluţii - o submulţime cu k elemente - sesizându-se când suma elementelor
vectorului generat este k. În momentul determinării unei submulţimi, aceasta este trecută într-un vector,
generându-se astfel P({1, 2,..., n}).
function suma(t,k:byte):boolean;
var
s,i:byte;
begin
s:=0;
for i:=1 to t do s:=s+x[i];
if s<=k then suma:=true
20
else suma:=false;
end;
function sumaf:byte;
var
s,i:byte;
begin
s:=0;
for i:=1 to n do s:=s+x[i];
sumaf:=s;
end;
procedure back(k,t:byte);
var
i:byte;
begin
if (t=n+1) then
if(sumaf=k) then
begin
inc(nr);
for i:=1 to n do tot[nr][i]:=x[i];
end
else
else
for i:=2 downto 1 do
begin
x[t]:=i-1;
if suma(t,k) then back(k,t+1);
end;
end;
begin
readln(n);
nr:=0;
for dim:=1 to n do back(dim,1);
writeln('Submultimile sunt:');
for k:=1 to nr do
begin
for j:=1 to n do
if tot[k][j]=1 then write(j,' ');
writeln;
end;
end.
Exerciţiul 5
21
determinarea valorilor şi vectorilor proprii corespunzători matricei de covarianţă calculată pe o
selecţie dată de vectori aleatori.
Soluţie: Fie X un vector aleator cu medie µ şi matrice de covarianţă Σ , {X1, X2,..., Xm} o selecţie
bernoulliană de volum m asupra lui X.
1 m
• media de selecţie se calculează astfel: µ =
m i=1∑Xi ;
1 m
•
matricea de autocorelaţie de selecţie este dată prin formula: S = ∑
m i=1
X i X Ti = ∑ + µµ
T;
• cum matricea de covarianţă de selecţie este simetrică şi pozitiv definită, rezultă că se poate
aplica algoritmul lui Jacobi [citarea algoritmului]; valorile proprii vor fi reale, pozitive, iar vectorii proprii
vor avea componente reale.
Unitatea completă este:
unit stat;
interface
type vect_ra=array[1..30] of real;
selectie=array[1..50] of vect_ra;
matrice=array[1..30,1..30] of real;
procedure media(var s:selectie; var
med:vect_ra;dim_v,vol_sel:byte);
procedure covarianta(var s:selectie;var
sigma:matrice;dim_v,vol_sel:byte);
procedure autocorelatie(var s:selectie;var
auto:matrice;dim_v,vol_sel:byte);
procedure vect_val_pr(var sel:selectie;var val_pr:vect_ra;
var vect_pr: matrice; dim_v, vol_sel:byte; eps:real; itmax:word);
implementation
procedure media;
var i,j:byte;
begin
for i:=1 to dim_v do
begin
med[i]:=0;
for j:=1 to vol_sel do
med[i]:=med[i]+s[j][i];
med[i]:=med[i]/vol_sel;
end;
end;
procedure covarianta;
var
i,j,k:byte;
medie:vect_ra;
begin
22
media(s,medie,dim_v,vol_sel);
for i:=1 to dim_v do
for j:=1 to dim_v do
begin
sigma[i,j]:=0;
for k:=1 to vol_sel do
sigma[i,j]:=sigma[i,j]+
(s[k][i]-medie[i])*(s[k][j]-medie[j]);
sigma[i][j]:=sigma[i,j]/(vol_sel-1);
end;
end;
procedure autocorelatie;
var
i,j,k:byte;
begin
for i:=1 to dim_v do
for j:=1 to dim_v do
begin
auto[i,j]:=0;
for k:=1 to vol_sel do
auto[i,j]:=auto[i,j]+s[k][i]*s[k][j];
auto[i][j]:=auto[i,j]/vol_sel;
end;
end;
procedure vect_val_pr;
var
i,it,j,k:byte;
aii,aji,ajj,amax,c,c1,s,t,inter,inter1:real;
sigma:matrice;
begin
it:=0;
covarianta(sel,sigma,dim_v,vol_sel);
for i:=1 to dim_v do
begin
for j:=1 to dim_v do
vect_pr[i][j]:=0;
vect_pr[i][i]:=1;
val_pr[i]:=sigma[i,i];
end;
amax:=1;
while((amax>eps)and(it<itmax)) do
begin
inc(it);amax:=0;
for j:=2 to dim_v do
for i:=1 to j-1 do
begin
aii:=val_pr[i];ajj:=val_pr[j];
aji:=abs(sigma[j,i]);
if(amax<aji) then amax:=aji;
if(aji>eps) then
23
begin
c:=0.5*(aii-ajj)/sigma[j,i];
t:=1/(abs(c)+sqrt(1+c*c));
if c<0 then t:=-t;
c:=1/sqrt(1+t*t);s:=c*t;
for k:=1 to i-1 do
begin
t:=sigma[i,k]*c+sigma[j,k]*s;
sigma[j,k]:=sigma[j,k]*c-sigma[i,k]*s;
sigma[i,k]:=t;
end;
for k:=i+1 to j-1 do
begin
t:=sigma[k,i]*c+sigma[j,k]*s;
sigma[j,k]:=sigma[j,k]*c-sigma[k,i]*s;
sigma[k,i]:=t;
end;
for k:=j+1 to dim_v do
begin
t:=sigma[k,i]*c+sigma[k,j]*s;
sigma[k,j]:=sigma[k,j]*c-sigma[k,i]*s;
sigma[k,i]:=t;
end;
for k:=1 to dim_v do
begin
t:=vect_pr[k,i]*c+vect_pr[k,j]*s;
vect_pr[k,j]:=vect_pr[k,j]*c-
vect_pr[k,i]*s;
vect_pr[k,i]:=t;
end;
t:=2*s*c*sigma[j,i];
val_pr[i]:=aii*c*c+ajj*s*s+t;
val_pr[j]:=aii*s*s+ajj*c*c-t;
sigma[j,i]:=0;
end;
end;
end;
for i:=1 to dim_v-1 do
for j:=i+1 to dim_v do
if(val_pr[i]<val_pr[j]) then
begin
inter:=val_pr[i];val_pr[i]:=val_pr[j];val_pr[j]:=inter;
for k:=1 to dim_v do
begin
inter1:=vect_pr[k,i];
vect_pr[k,i]:=vect_pr[k,j];
vect_pr[k,j]:=inter1;
end;
end;
end;
end.
24
Exerciţii propuse
1. Să se scrie programul Pascal pentru determinarea celui mai mic multiplu comun al n numere.
2. Să se scrie un subprogram Pascal pentru a decide dacă două numere naturale sunt prime între ele.
3. Să se scrie programul Pascal pentru generarea tuturor numerelor prime mai mici decât n, n citit de la
tastatură.
4. Să se scrie un subprogram Pascal pentru calculul celui mai mare divizor comun a n numere naturale,
n≥ 3.
5. Să se scrie un subprogram Pascal pentru descompunerea unui număr natural în factori primi.
6. Să se scrie programul Pascal pentru generarea tuturor combinărilor de k elemente ale unei mulţimi
de n elemente, n≥ k.
7. Să se scrie un subprogram Pascal pentru calculul valorii unui polinom într-un punct dat.
8. Să se scrie un subprogram Pascal pentru calculul derivatei unui polinom.
9. Să se scrie un subprogram Pascal pentru determinarea compunerii a două polinoame.
10. Utilizând algoritmul lui Euclid, să se scrie subprogramele Pascal pentru determinarea celui mai
mare divizor comun şi a celui mai mic multiplu comun pentru două polinoame.
11. Să se realizeze programul Pascal pentru calculul polinomului de interpolare Lagrange, pentru un
set de perechi {(x1,y1),(x2,y2),…,(xn, yn)}, citite de la tastatură.
25
Exercitiul 1.
Sa se scrie un program care citeste un text (maxim 255 caracter) de la tastatura si il afiseaza
compactat, prin eliminarea spatiilor suplimentare.
Rezolvare: Necesitatea compactarii apare in trei situatii diferite: exista caractere spatiu la inceputul
textului sau la sfirsitul sau (acestea se vor elimina in totalitate) sau exista mai mult de un caracte
intre cuvinte, caz in care se va pastra numai un caracter, restul eliminindu-se. Prin cuvint se intelege
un subsir de caractere intre care nu exista nici un spatiu. Algoritmul parcurge sirul intr-o bucla
WHILE-DO, verificind fiecare caracter;
daca nu este spatiu se trece la caracterul urmator (caracterul curent este indicat de contorul i); daca
caracterul curent este spatiu trebuie trebuie sa decidem daca il eliminam sau il pastram. Caracterul
trebuie eliminat daca este primul din sir, ultimul din sir sau desparte doua cuvinte iar urmatorul
caracter este tot spatiu. Iesirea din bucla se petrece atunci cind contorul I are o valoare mai mare
decit lungimea sirului (indica un carater aflat 'dincolo' de sfirsitul sirului). Daca decidem sa pastram
spatiul, se trece la urmatorul caracter, prin incrementarea contorului i. Daca dorim sa eliminam
caracterul se procedeaza astfel: 1) toate caracterele care urmeaza in sir vor fi mutate cu o pozitie
spre inceputul sirului; 2) se inscrie in s[0] noua lungime a sirului (cu 1 mai mica decit cea
anterioara).
program compactare_sir;
var s:string;
i,j,l:byte;
begin write('Textul de compactat: ');
readln(s);
l:=length(s);
i:=1;
while i<=l do
begin if s[i]<>' ' then inc(i)
else begin if (i=1) or (i=l) or (s[i+1]=' ') then
begin for j:=i to l-1 do
s[j]:=s[j+1];
dec(l);
s[0]:=chr(l);
end
else inc(i);
end;
end;
writeln(s);
readln;
end.
Exemplu de rulare:
26
Exercitiul 2.
Sa se scrie un program care numara cuvintele dintr-un text.
program numara_cuvinte;
var s:string;
i,n,l:byte;
begin write('Textul de prelucrat:');
readln(s);
l:=length(s);
n:=0;
for i:=1 to l-1 do
if (s[i]=' ') and (s[i+1]<>' ') then
inc(n);
writeln('Textul contine ',n,' cuvinte.');
readln;
end.
Exemplu de rulare:
Textul de prelucrat: Programul va numara cuvintele acestui text.
Textul contine 6 cuvinte.
Exercitiul 3.
Sa se relizeze un program care introduce cite un spatiu intre fiecare 2 caractere diferite de spatiu ale
unui sir citit de la tastatura. Observatie: sirul initial va avea maxim 122 caractere pentru a evita
problemele legate de depasirea lungimii maxime a unui sir.
Rezolvare: Vom trata sirul de caractere tot ca vector. Intr-o bucla WHILE-DO se va parcurge sirul
caracter cu caracter pina cind contorul va depasi sfirsitul acestuia. Daca intilnim doua caractere,
ambele diferite de spatiu, se mareste lungimea sirului cu 1, se deplaseaza restul sirului spre dreapta
cu o pozitie (spre sfirsitul sirului) iar in pozitia i+1 (deci intre cele 2 caractere detectate anterior) se
inscrie un caracter spatiu.
program extindere;
var s:string;
l,i,j:byte;
begin write('Sirul initial: ');
readln(s);
l:=length(s);
i:=1;
while i<=l do
begin if (s[i]<>' ') and (s[i+1]<>' ') then
begin l:=l+1;
27
s[0]:=chr(l);
for j:=l downto i+2 do
s[j]:=s[j-1];
s[i+1]:=' ';
i:=i+2;
end
else i:=i+1;
end;
writeln(s);
readln;
end.
Exemplu de rulare:
Exercitiul 4.
Sa se scrie un unit cu subprograme care realizeaza urmatoarele prelucrari:
1. codificarea/decodificarea unui sir de caractere prin metoda ROT13;
2. codificarea/decodificarea unui sir prin interschimbarea grupurilor de 4 biti;
3. contorizarea numarului de aparitii ale fiecarul caracter ASCII intr-un sir.
Rezolvare:
1. Metoda ROT13 presupune rotirea setului de caractere ASCII cu 13 pozitii. Astfel litera A devine
N, B devine O, a devine n si asa mai departe. Algoritmul presupune parcurgerea sirului intr-o bucla
FOR-DO si inlocuirea fiecarui caracter cu caracterul care are codul ASCII mai mare cu 13. Daca se
depaseste valoarea maxima (255) - adica se trece dincolo de sfirsitul setului ASCII - se reia
numaratoarea de la inceputul setului. Decodificare este asemanatoare, cu diferenta ca se inlocuiesc
caracterele cu cele care au, respectiv, codul ASCII cu 13 mai mic. Procedurile primesc ca parametru
sirul care trebuie (de)codificat.
3. Pentru numararea aparitiilor fiecarui caracter intr-un sir se foloseste un vector initializat cu valori
nule, cu atitea elemente cite caractere are setul ASCII. Fiecare element al vectorului va contoriza
aparitiile caracterului cu codul ASCII corespunzator (astfel elementul cu numarul 64 va arata
28
numarul aparitiilor caracterului A, 65 pentru B etc.). Intr-o bucla FOR-DO se parcurge sirul si,
pentru fiecare caracter este incrementat elementul corespunzator din vector (dat de codul ASCII al
caracterului, disponibil prin apelarea functiei ORD).
unit codif;
interface
type vector=array[0..255]of byte;
const hi=$f0;
lo=$0f;
procedure codrot13(var s:string);
procedure decodrot13(var s:string);
procedure codec4b(var s:string);
procedure contor(s:string; var nr:vector);
implementation
end.
29
Exemplu de program apelator:
program apel;
uses codif;
var s:string;
x:vector;
i,k:byte;
begin write('Sirul de prelucrat: ');
readln(s);
write(‘Sirul de prelucrat: ');
writeln('Codificare/decodificare ROT13:');
codrot13(s);
writeln(s);
decodrot13(s);
writeln(s);
writeln(‘'Codificare/decodificare 4b:');
codec4b(s);writeln(s);
codec4b(s);writeln(s);
writeln('Statistica caractere:');
contor(s,x);
k:=1;
for i:=0 to 255 do begin if x[i]<>0 then begin write(chr(i):1,' - ',x[i]:2,' ');
inc(k);
end;
if k mod 7=0 then writeln(' ');
end;
readln;
end.
Exemplu de rulare:
Exercitiul 5.
Sa se scrie un subprogram care insereaza intr-un sir un alt sir in pozitia imediat urmatoare primei
apariti a unui caracter dat; daca acesta nu este gasit atunci inserarea se face la sfirsit.
Rezolvare: Primul pas este determinarea pozitiei in care se va insera al doilea sir. In acest scop se
parcurge sirul initial intr-o bucla WHILE-DO pina la detectarea caracterului dupa care se insereaza.
La iesirea din bucla variabila i va indica pozitia caracterului dupa care se insereaza; adaugind 1
obtinem pozitia in care se insereaza. Pasul urmator consta in inscrierea noii lungimi a sirului
(lungimea initiala + lungimea sirului care se insereaza) in pozitia 0. Caracterele din pozitia i pina la
sfirsitul sirului initial trebuie deplasate la dreapta pentru a face loc sirului care se insereaza. Ultimul
pas este copierea caracterelor sirului de inserat in sirul initial, din pozitia i.
30
procedure inser(var s:string;ss:string;c:char);
var i,j,l,ll:byte;
vb:boolean;
begin i:=1;
vb:=false;
l:=length(s);ll:=length(ss);
while (i<l) and (not vb) do
begin if s[i]=c then vb:=true
else inc(i);
end;
i:=i+1;
s[0]:=chr(l+ll);
for j:=0 to l-i do
s[l+ll-j]:=s[l-j];
for j:=1 to ll do
s[i+j-1]:=ss[j];
end;
Exemplu de rulare:
Exercitiul 6:
Sa se scrie un subprogram care sterge dintr-un sir un subsir dat (prima aparitie a subsirului).
Rezolvare: pentru a pute sterge subsirul, acesta trebuie intii localizat in sirul initial. Daca notam cu l
lungimea sirului initial si cu ll lungimea subsirului de sters, atunci inceputul acestuia poate fi
oriunde intre pozitia 1 si l-ll in sirul initial. Se parcurge sirul s intr-o bucla WHILE-DO pina cind se
depaseste pozitia l-ll sau a fost detectat si sters subsirul dat. O posibila aparitie a subsirului este
luata in calcul atunci cind caracterul curent din s este identic cu primul caracter din subsirul de sters
(ss). Atunci cind se intilneste o astfel de situatie se verifica daca intr-adevar s-a intilnit subsirul ss;
pentru aceasta se compara caracter cu caracter sirul s, din pozitia curenta, pe o lungime ll cu
subsirul ss. Daca nu se intilneste nici o diferenta se sterge subsirul si se marcheaza prin variabila
booleana vb terminarea prelucrarilor. Pentru stergere se deplaseaza toate
caracterele ramase din sirul s, din pozitia curenta+ll, cu ll pozitii la stinga si se inscrie noua lungime
a sirului s in pozitia s[0].
31
begin if s[i]<>ss[1] then inc(i)
else begin vb1:=true;
for j:=1 to ll do
if ss[j]<>s[i+j-1] then vb1:=false;
if vb1 then
begin vb:=true;
for j:=i+ll to l do
s[j-ll]:=s[j];
s[0]:=chr(l-ll);
end
else inc(i);
end;
end;
end;
Exemplu de rulare:
Exercitiul 7.
{Sa se scrie un subprogram care numara aparitiile unui subsir intr-un sir de caractere dat. Nu este
obligatoriu ca aparitiile subsirului sa fie disjuncte.
Rezolvare: Se parcurge sirul initial, s, pentru a detecta posibile aparitii ale subsirului de cautat. In
acest scop se cauta primul caracter al subsirului, intre pozitia 1 si l-ll din sirul initial, unde l este
lungimea sirului initial iar ll lungimea subsirului. Daca se intilneste o egalitate, atunci se verifica
daca intr-adevar s-a detectat subsirul cautat, prin compararea caracter cu caracter, din pozitia
curenta, pe o lungime de l caractere, cu sirul de cautat. Daca nu se intilnesc diferente, se
incrementeaza numarul de aparitii detectate ale sirului ss.
32
end;
Exemplu de rulare:
Exercitii propuse:
Sa se scrie un subprogram care sa inlocuiasca intr-un sir dat toate aparitiile unui subsir cu un
alt sir de caractere.
Sa se scrie un subprogram care transforma caracterele unui text astfel incit prima litera din
fiecare fraza sa fie majuscula iar restul litere mici. Frazele se incheie cu caracterul punct.
Sa se scrie un subprogram care transforma toate caracterele majuscule dintr-un text in litere
mici si invers.
Sa se scrie un subprogram care cauta cel mai lung subsir sortat crescator intr-un sir dat.
33
LUCRUL CU MASIVE DE DATE
Exerciţiul 1
Unitatea Pascal:
unit multimi;
interface
type multime=array[1..50] of integer;
produs=array[1..100] of record x,y:integer end;
procedure reuniune(m,n:byte; var a,b,c:multime; var card:byte);
procedure intersectie(m,n:byte; var a,b,c:multime; var card:byte);
procedure diferenta(m,n:byte; var a,b,c:multime; var card:byte);
procedure produs_cartezian(m,n:byte; var a,b:multime; var c:produs);
implementation
34
end;
begin
sortare(n,v);
k:=0; i:=1;
while i<=n-k do
if v[i]=v[i+1] then begin
k:=k+1;
for j:=i to n-k+1 do v[j]:=v[j+1]
end
else inc(i);
n:=n-k
end;
procedure reuniune;
const hv=maxint;
var i,j,k,l:byte;
begin
k:=0; i:=1; j:=1;
while (a[i]<>hv) or (b[j]<>hv) do
if a[i]<b[j] then begin
inc(k);
c[k]:=a[i];
inc(i);
if i>m then a[i]:=hv
end
else if a[i]>b[j] then begin
inc(k);
c[k]:=b[j];
inc(j);
if j>n then b[j]:=hv
end
else begin inc(i); if i>m then a[i]:=hv end;
card:=k
end;
procedure intersectie;
var i,j,k:byte;
begin
k:=0; i:=1; j:=1;
while (i<=m) and (j<=n) do
if a[i]=b[j] then begin
inc(k);
c[k]:=a[i];
i:=i+1
end
else if a[i]>b[j] then inc(j) else inc(i);
card:=k
end;
35
procedure diferenta;
var i,j,k:byte;
begin
k:=0;
for i:=1 to m do begin
j:=1;
while (a[i]<>b[j]) and (j<=n) do inc(j);
if j>n then begin inc(k);
c[k]:=a[i]
end
end;
card:=k
end;
procedure produs_cartezian;
var i,j,k:byte;
begin
k:=0;
for i:=1 to m do
for j:=1 to n do
begin
inc(k);
c[k].x:=a[i];
c[k].y:=b[j]
end
end;
end.
Exerciţiul 2
Să se proiecteze o unitate Pascal care să conţină subprograme pentru calcularea următorilor indicatori
statistici: media aritmetică ponderată, dispersia şi abaterea medie pătratică pentru un şir de observaţii
statistice.
Soluţie: Pentru rezolvarea problemelor statistice trebuie avute în vedere, pe lângă observaţiile propriu-zise,
şi frecvenţele de apariţie a acestora în cadrul şirului iniţial. În cadrul unităţii au fost dezvoltate două
subprograme frecvente_1 şi frecvente_2, care reprezintă variante ale aceleiaşi probleme.
Prima variantă determină vectorul valorilor caracteristicii observate (unice), precum şi vectorul de
frecvenţe, prin parcurgerea secvenţială a şirului iniţial de observaţii statistice. Pentru fiecare observaţie
iniţială se verifică existenţa în vectorul de valori unice: dacă există, atunci se incrementează frecvenţa
corespunzătoare valorii respective, în caz contrar observaţia are o valoare nouă şi se adaugă şirului de valori
unice.
A doua variantă presupune sortarea şirului iniţial de observaţii statistice şi obţinerea vectorului
valorilor caracteristicii observate (unice) şi a vectorului de frecvenţe folosind algoritmul controlului după
caracteristică.
Formulele utilizate pentru determinarea indicatorilor statistici sunt:
n
∑x i ⋅ fi
Media: x= i =1
n
;
∑f
i =1
i
36
∑ (x )
n
2
i − x ⋅ fi
Dispersia: σ2= i =1
n ;
∑f
i =1
i
Unitatea Pascal:
unit statist;
interface
type vector=array[1..50] of real;
vector1=array[1..50] of byte;
procedure frecvente_1(n:byte; var x,y:vector; var f:vector1; var k:byte);
procedure frecvente_2(n:byte; var x,y:vector; var f:vector1; var k:byte);
function media(n:byte; var x,y:vector; var f:vector1):real;
function dispersia(n:byte; var x,y:vector; var f:vector1):real;
function abaterea_medie_patratica(n:byte; var x,y:vector; var f:vector1):real;
implementation
procedure frecvente_1;
var i,j:byte;
begin
y[1]:=x[1]; f[1]:=1; k:=1;
for i:=2 to n do
begin
j:=1;
while (x[i]<>y[j]) and (j<=k) do inc(j);
if j<=k then inc(f[j])
else begin
inc(k);
37
y[k]:=x[i];
f[k]:=1
end
end
end;
procedure frecvente_2;
var i:byte;
begin
sortare(n,x);
k:=0; i:=1;
while i<=n do
begin
k:=k+1;
y[k]:=x[i];
f[k]:=0;
while (x[i]=y[k]) and (i<=n) do
begin
inc(f[k]);
inc(i)
end
end
end;
function media;
var s:real; dim,i:byte;
begin
frecvente_1(n,x,y,f,dim);
if dim=n then begin
s:=0;
for i:=1 to n do s:=s+x[i];
media:=s/n
end
else begin
s:=0;
for i:=1 to dim do s:=s+y[i]*f[i];
media:=s/n
end
end;
function dispersia;
var m:real; dim,i:byte; s:real;
begin
m:=media(n,x,y,f);
frecvente_2(n,x,y,f,dim);
s:=0;
for i:=1 to dim do s:=s+sqr(y[i]-m)*f[i];
dispersia:=s/n
38
end;
function abaterea_medie_patratica;
begin
abaterea_medie_patratica:=sqrt(dispersia(n,x,y,f))
end;
end.
Exerciţiul 3
program quick_sort;
uses crt;
var
x:array[1..100] of integer;
n,i:byte;
procedure poz(p,u:byte; var k:byte);
var
i,j:byte;
l,di,dj:shortint;
{di, dj sunt pasii de incrementare pentru i si j, indicand sensul parcurgerii}
v:integer;
begin
i:=p;j:=u;di:=0;dj:=-1;
while i<j do
if x[i]>x[j] then
begin
v:=x[i];
x[i]:=x[j];
x[j]:=v;
l:=di;di:=-dj;dj:=-l;
i:=i+di;j:=j+dj
end
else begin
i:=i+di;j:=j+dj
end;
k:=i
39
end;
procedure quick(p,u:byte);
var
i:byte;
begin
if p>=u then
else begin
poz(p,u,i);
quick(p,i-1);
quick(i+1,u)
end
end;
Exerciţiul 4
program inter_sort;
uses crt;
var
n,i:word;
v:array[1..1000] of real;
par:array[1..1000] of real;
procedure interc(l,m,r:word);
var i,j,k:word;
begin
if l<r then begin
i:=l;
j:=m+1;
k:=1;
while(i<=m) and (j<=r) do
40
begin
if v[i]<v[j] then begin
par[k]:=v[i];
i:=i+1;
k:=k+1
end
else begin
par[k]:=v[j];
j:=j+1;
k:=k+1
end
end;
if i<=m then
for j:=i to m do
begin
par[k]:=v[j];
k:=k+1
end
else
for i:=j to r do
begin
par[k]:=v[i];
k:=k+1
end
end;
for i:=0 to r-l do
v[l+i]:=par[i+1]
end;
procedure inters(l,r:word);
var i:word;
begin
if l<r then begin
i:=(l+r)div 2;
inters(l,i);
inters(i+1,r);
interc(l,i,r)
end
end;
begin {program principal}
clrscr;
write('Dimensiunea vectorului:');
readln(n);
write('Elementele vectorului:');
for i:=1 to n do begin
write('v[', i , ']= ');
readln(v[i])
end;
inters(1,n);
41
for i:=1 to n do write(v[i],' ')
end.
Exerciţiul 5
Să se determine coincidenţele produse în cadrul modelului unei linii telefonice, pe un interval de timp
prestabilit, dându-se parametrii repartiţiilor exponenţiale (λ şi µ ) care caracterizează apelurile, precum şi
duratele convorbirilor.
program apeluri;
uses crt;
type sir=array[1..100] of real;
var
A,D:sir;
P:array[1..100] of integer;
T,lambda,miu,suma:real;
i,j,k,numar:integer;
indic:boolean;
procedure expon(medie:real;var x:real);
begin
x:=-ln(random)/medie
end;
begin
clrscr;
randomize;
suma:=0;
readln(lambda);
readln(miu);
readln(T);
i:=0;
repeat
i:=i+1;
expon(lambda,A[i]);
expon(miu,D[i]);
suma:=suma+A[i]
until suma>T;
numar:=i; k:=0;
for i:=1 to numar do
begin
indic:=true;
for j:=1 to numar do
if((abs(A[i]-D[j])<0.11) and indic) then
begin
k:=k+1;
P[k]:=i;
indic:=false
end
end;
42
writeln('Numarul apelurilor telefonice este: ',numar);
for i:=1 to k do
writeln('S-a realizat o coincidenta la apelul ',P[i])
end.
Exerciţiul 6
Dându-se o matrice P pătratică, pozitiv definită, reală şi simetrică, să se determine un bloc inferior
triunghiular T, cu proprietatea: P=T * Transpus(T).
Soluţie: Se foloseşte algoritmul lui Crout de stabilire a blocului T.
program Crout;
uses crt;
var
P: array [1..10,1..10] of real;
T: array [1..10,1..10] of real;
i,j,k,l,n:integer;
suma:real;
begin
clrscr;
readln(n);
suma:=0;
for i:=1 to n do
for j:=1 to n do
readln(P[i,j]);
T[1,1]:=sqrt(P[1,1]);
for i:=2 to n do T[i,1]:=P[i,1]/T[1,1];
for i:=2 to n do begin
for j:=1 to i-1 do
suma:=suma+T[i,j]*T[i,j];
T[i,i]:=sqrt(P[i,i]-suma)
end;
suma:=0;
for j:=1 to n do
for i:=j+1 to n do begin
for k:=1 to j-1 do
suma:=suma+T[i,k]*T[j,k];
T[i,j]:=sqrt(P[i,j]-suma)
end;
for i:=1 to n do begin
for j:=1 to n do
write(T[i,j],' ');
writeln
end
end.
43