'
INFORMATIC
Refereni tiinifici :
l. Tudor. Sorin
004(075.35)
..~ ..- .."' Definiia 1.1. Un tablou este o structur omogen (format din elemente
~
.$ lntrebri posibile
a) Dac magazinul vinde 5 produse, cte elemente are tabloul?
b) Care sunt indicii de adresare n tablou pentrt.~ a afla vnzrile din produsul
5 n luna septembrie? -
c) Cum se poate calcula suma ncasat n luna mai?
8 Capitolul 1. Tablouri
e) Cum putem determina produsul din vnzarea cruia s-a incasat anual
suma maxim?
f) Care este luna cu cele mai mari ncasri?
2. Tot aa, se poate memora, sub form de tablou, situaia la nvtur a celor m
elevi ai unei clase. Dac numerotm elevii cu 1, 2, ... , m i materiile pe care acetia
le studiaz cu 1, 2, ... , n , atunci a 1 d reprezint media pe care o are elevul i la
materia j.
J~ ntrebri posibile
a) Dac n clas sunt 30 de elevi i acetia studiaz 8 materii, cte elemente
are matricea?
b) Care este materia la care elevii au cele mai bune rezultate?
c) Care este media general a elevului i?
d) Care este media general a elevilor unei clase?
irul exemplelor ar putea continua pentru c sunt foarte multe situaii in care
se utilizeaz tablouri bidimensionale (matrice).
var astablou1
sau direct
var asarray [1 10,1 9) of real;
+ n Pascal, matricea are liniile 1,2,... ,10 i coloanele 1,2, ... ,9 i, de exemplu,
elementul de pe linia a treia i coloana a patra se adreseaz prin a [ 3, 4 l .
+ n C++, matricea are liniile 0,1, ... ,9 i coloanele 0,1, ... ,8 i, de exemplu,
elementul de pe linia a treia i coloana a patra se adreseaz prin a[2] [3] .
Uneori, pentru simplitate, vom folosi liniile i coloanele matricei Tncepand de
la 1 . ln aceste cond iii se pierde o linie i o coloan, fJecare de indice o.
Consideram acest fapt neesenial.
Manual de Informatic pentru clasa a Xl-a 9
Programul care-I utilizeaza va f unciona corect daca avem cel mult a linii i
cel m uit s coloane.
(~ !!]
n urma interschimbrii liniilor 2 i 3 se obine:
afiate
(CJ]
in ordinea:
Elementele vor fi
1 2 3 6 9 8 7 4 5.
/-------"'
char
n,m,i,j,dir:~e;
int n,m,i,j,dir,p,pt;
p,pt ~integer;
ifstream f(tabla.txt);
f:textl
begin
void main()
aaaign(f, 1 tabla.txt 1 )1 {
reaet(f); f>>n>>m;
readln(f,n,m); for(ilti<nti++)
for i ~l to n do for(:f1I:f <ml:f++)
begin f.a [il [j) 1
for jsl tom do pt=O;
read(f,a[i,:fl)l for(i=1;i< nii++)
readln(f) for(jll:f <-.m;:f++)
endl if (a[i][:fll 1 , ' )
pt ~o,
{
for i ~1 to n do if(a[ill:fl 'A'I 1
for j :,.1 to m do 1
if a[i,j]<>',' then a[i) [j] E' 11
a[i) [:fl 'J:'
begin
a[i) [:fl 1 0' 1
if (a[i,j]c'A') or a[iJ[:fl 'U')
(a[i.j)'E') or p=li
(a[i,:f] 1 l: 1 ) or alsa p:ZI
(a[i, j)= 1 0') or dirQI
(a[i,:f]= 1 U') then P ~1 if (i>l && a[i-1] [:f]l', 1
1
a o, i~ 1
1 &n+l, i~ 1
1
~
14 Capitolul 1. Tablouri
Se mai poate analiza i cazul in care o liter nu are nici un vecin pe niciuna
dintre d ireciile orizontal sau vertical (caz Tn care litera nu s-ar puncta deloc), ns
problema precizeaz c literele sunt aezate corect conform jocului de scrabble,
deci nu pot fi amplasate litere izolate.
Pentru memorarea numerelor care aparin fiecrei clase vom utiliza o matrice,
denumit Mat, cu 10 coloane, in care prima linie are indicele o. Elementele din linia o
rein numrul de elemente din ir care se gsesc pe coloana respectiv:
o 1 2 3 4 5 6 7 8 9
11 215
1 :: 1 . 1 o 1 o 1 o 1 1 .:. 1 o 1 o 1 o 1
1: 1 o 1
215
1 :~ 1 :: 1 o 1 o 1 o 1 o 1o 1
Manual de informatic pentru clasa a Xl-a 15
~ Observaii
../ Dac k este numrul maxim de cifre a numerelor din ir, operaia de
mprire a numerelor n 10 clase se va relua de k ori.
(~}
elementele sunt: 1 , s i 9.
Se cere:
tele aflate pe
b) Pentru un tablou ptratic A, numim diagonal secundar, elemen
unia" care unete A (n, 11 cu A [l,nl .
(~}
elementele sunt: 7 , s i 3.
Se cere:
n linia k ,
2. lnterschimbai coloanele unei matrice c1~ m linii i n coloane astfel nct
elementele s fie in ordine cresctoare.
Manual de informatic pentru clasa a Xl-a 17
3. Un teren este dat sub forma unui tablou A cu n linii i m coloane. Elementul
A [i 1 j l reine altitudinea ptrelului de coordonate i i j. S se afieze
coordonatele "ptrelelor vrf" (un ptrel este vrf dac toi vecinii si au o
altitudine strict mai mic).
../ Indicaie. Atenie! Maximele sau minimele pe linii sau coloane pot s nu fie
unice. Dac vom considera numai o valoare dintre acestea, s-ar putea s pierdem
soluii.
Exemplu: m=4 , n=4. Matricea iniial i submatricele sunt prezentate mai jos:
1 2 3 lf
5 G7 8 1 2 3 2 3 lf 5 G7 G7 8
9 H> 11 12 5 G7 G7 8 9 1 o 11 10 11 12
13 1LJ 15 1G 9 1o 11 10 11 12 13 1lf 15 1LJ 15 1G
10. Fiind dat o matrice cum linii i n coloane, se cere s se afieze elementele n
ordinea sugerat n figura de mai jos:
.+
i~
Figura 1.2. Exemplu
18 Capitolul 1. Tablouri
a)
for j:=l tom do
V[j+(i-l)*m):=Mat[i,j]; V[j+(i-l)*m)Mat[i] [j];
!>) for i:l to m do b) for (il;i<-m;i++l
for j:=1 to n do for (j1;j<n;j++)
V[j+(i-l)*n):Mat[i,j]; V[j+(i-l)*nJ=Mat[i] [j];
C} for i:=l tom do c) for (i1;i<m;i++)
for j:=l ton do for (j=l;j<=n;j++)
V[i+(j-l)*n] :~Mat[i,j]; V[i+ (j-1) *nl Mat [i) [j);
d) for i: l to m do d) for (il;i<m;i++l
for j:l ton do for (j1d<=nd++)
V[j+(i-1)*n] :Mat[j,i); V[j+(i-1l*n]=Mat[i,j];
Subprograme
!
1+ x 2 '
f (x) = X + 1,'
pentru x e (- oo ,-1);
6
pentru x e ( 1, oo ).
1+ X
Se citesc dou valori reale a i b. S se scrie un program care afieaz care dintre
valorile f (a> i f (b) este cea mai mare.
ln plus, dac ntr-un alt program este necesar sortarea altui vector de
~u mere reale, metoda clasic ne permite s alegem din secvena de instruciuni ce
'ormeaz programul pe cele ce realizeaz sortarea, s le copiem Tn noul program
t s facem eventualele adaptri (numrul de componente i numele vectorului pot
1 altele). Aceste operaii sunt destul de greoaie i necesit mult atenie. Prin
mplementarea modular, cu ajutorul subprogramelor, "preluarea" se realizeaz
mult mai uor.
-+ Funcia are variabile proprii - adic variabile care sunt definite n cadrul el. n
exemplu, ele sunt s i i . Aceste variabile se numesc variabile locale.
var n:integer;
function subp(n:integer)z real;
var szreal;
i:integer;
begin
s:=O;
for i:1 to n do s:s+1/i;
subp:s;
end;
begin
write ('n'); readln(n);
write(subp(n):5: 2);
end.
var n,i:integer;
rez,prodzreal;
function subp(nzinteger)z real;
var szreal;
i:integer;
begin
s:=O;
for izl to n do s:s+l/i;
subp:s;
and;
begin
write ('n'); readln(n);
rez:subp(n);
prod:l;
for izl to n do prodzprod*rez;
write(prodz5:2);
end.
La apel, lucrurile stau altfel: valorile acestora sunt cunoscute. Prin urmare
acetia se numesc parametri efectlvl.
24 Capitolul 2. Subprograme
procedur a nume;
begin
end;
Vanual de informatic pentru clasa a Xl-a 25
----------------~----------------------------------------
+ Apelul unei proceduri se face prin utilizarea numelui ei, sub forma nume 1
Mai precis, apelul unei proceduri este instruciun~, numit instruciunea
de apel.
-+ La apel, controlul programului este transferat la prima instruciune a
procedurii - dup cum se ntmpl i la funcii. Dup executarea procedurii,
se revine in programul principal/a prima instruciune care urmeaz celei de
apel- n cazul de fa se ntlnete o alt instruciune de apel.
~ Ca i funciile, procedurile se pot plasa n cadrul programului intre
declaraiile de variabile i instruciunea compusfJ.
l
n acest exemplu, procedurile sunt apelate fr utilizarea parametrilor. n
realitate, procedurile pot avea parametri ntocmai ca i funciile.
LISTA
ANTET DE
--FUNCIE PARAMETRI
FORMALI
IDENTIFICATOR
DE TIP
Exemplu:
function suma(x,y:int eger):real;
begin
sum.a:=x+y;
end
begin
suma:x+y;
end
LIST.J.
ANTET IDENTIFICATO R PARAMETRI
PROCEOURE
-PROCEDUR FORMALI
Exemplu:
procedura suma(var szreal; x,yzreal);
begin
SI"'X+y;
end;
- blocul este:
begin
SIX+y;
end;
v,a.,ual de informatic pentru clasa a Xl-a 27
Dei aparent asemntoare, cele dou noiun i difer . Buna nelegere a lor
-e aj ut s evitm anumite erori. Mai mult, aceste noiuni sunt utilizate de orice
,...baj de programare, nu numai de Pascal.
begin
x:=3;
t
end.
28 Capitolul 2. Subprowame
Exemple
Exemple
procedura sl;
begin
writeln( 'sl')
end;
procedura s2;
begin
sl;
writeln ( s2');
end;
begin
sl,;
s2;
end.
Procedura test conine definiia a dou proceduri sl i s2. Nici una din
aceste proceduri nu se consider declarat pentru programul principal.
Amndou sunt declarate pentru procedura test. Pentru procedura s2, sl
este declarat, dar pentru sl procedura s2 nu este declarat.
\1anual de informatic pentru clasa a Xl-a
29
end1
begin
test1
end.
proced ura b;
begin
writel n( 'Eu sunt b')
Glldl
begin
&1
end.
var p,x,yainteger;
begin
x:=2;
y:-3;
pa l+prod(x,y);
writeln(p)
end .
~b Observaii
-/ n cadrul expresiei, apelul este un operand. El Intr n calcul cu valoarea
returnat de funcie.
LIST
APEL IDENTIFICATOR PARAMETRI
FUNCIE FUNCIE
EFECTIV!
Cele cteva exemple date pn acum fac inutil prezentarea unui alt
exemplu. Trebuie s tim c:
Cunotinele dobndite pn in
acest moment nu permit o justificare
comp let. Putem spune numai c
utilizarea parametrilor permite ca subprogra
s fie scris independent de programu mul
l principal. S lum un exemplu: ni se cere
scriem un subprogram care calculeaz s
suma a dou valori reale. Ce adunm?
Pentru un program ar trebui s adunm x cu y, iar pentru altul, m cu n.
var x,y, sum :inte ger;
proc edur a sum a(a, b:in tege r; var
s:in tege r);
begi n
s:a +b;
end;
begi n
x:3 ; Yl=4 ;
sum a(x, y,su m); writ eln( sum );
suma(~,3,sum); writ eln(
sum );
end.
32 Capitolul 2. Subprograme
Exemple
type vector=array [1 9] of integer;
LIST
PARAM ETRI
EFECTI V!
EXPRESI E
Figura 2.5.
Sintaxa parametrilor trimii
ranual de informatic pentru clasa a Xl-a 33
n acest paragraf vom analiza modul prin care sunt memorai parametrii
""al1 smii n momentul lan srii n executare a subprogramului.
stiva~~~--3------4--~---a-d-re_s_a_v_a_ri_a_bi-le_i_s_um____~l
a b s
~a al doilea apel, parametrii sunt: 2, 3, sum.
);> valorile reinute de variabile - n acest caz, parametrii efectiv! trebuie s fie
numele variabilelor.
Exemplu:
var n:integer;
prooedure test(n:integer);
begin
n:=n+l;
writeln(n)
end;
begin
n:l;
test (n);
writeln(n);
end.
);> parametrii efectiv! sunt valori sau expresii, care mai nti se evalueaz.
Exemplu:
prooedure test(n:integer);
begin
writeln(n)
end;
begin
test(3);
test(3+4*5);
end.
anual de informatic pentru clasa a Xl- a 35
Exemplu:
program test_param;
var x,y:integer;
function suma (a,b:integer):int eger;
begin
suma:=a+b;
end;
function dif (a,b:integer):int eger;
begin
dif:=a-b;
end;
function prod(a,b:integer ):integer;
begin
prod:=a*b;
end;
begin
write('xa'); readln(x);
write('y='l; readln(y);
writeln(prod(dif (x,y),suma(x,y)) );
end.
? n acest caz, ne putem ntreba care este mecanismul prin care, dei pentru o
variabil transmis se reine adresa sa, n subprogram putem adresa
variabila normal (nu indirect)? La compilare, orice referin la variabila
respectiv, este "tradus" ca adresare indirect.
36 Capitolul 2. Subprograme
var x,y:integer;
procedura interschimb(var x,y:integer)l
var man:integer1
begin
man:x; XIYI Yl~l
end;
begin
x:21 yz.,3;
intarschimb(x,y);
writa(x, ,y);
end.
~'
]l.B
Definiia 2.7. Variabilele globale sunt variabilele programului principal.
Ele sunt rezervate ntr-o zon special de date, numit segment de date.
n versiunea 7 . o a limbajului Pascal, variabilele numerice sunt
iniializate cu o.
,
a;
end.
Alt termen des utilizat n practica programrii este durata de via a unei
-ariabile. El se refer la perioada de timp n care variabila este alocata n memorie.
!.stfel, avem:
durat static - variabila are alocat spaiu pe tot timpul executrii programului.
durata local - variabila are alocat spaiu doar n timpul ct se execut un
anumit bloc.
durat dinamic - alocarea spaiului de memorie se face n timpul executarii prin
subprograme speciale sau operatori (n Pascal avem subprograme speciale).
Variabilele cu aceast durat de via se numesc dinamice i nu se trateaz n
acest manual.
38 Capitolul 2. Subprograme
Reamintim faptul c un tip este standard dac este cunoscut de limbaj (de
exemplu, integer). n caz contrar tipul este nestandard (de exemplu, tipul care
descrie un vector cu componente de tip real) . lat o procedur scris greit:
procedura er (var Vlarray[1 99) of real);
begin
end;
endt
swna(n,i):=st
end;
IMPLEMEN'l'ATION
[tipuri de date i variabile locale (valabile numai pentru unitatea de
program)]
procedurile i funciile utilizate de unitatea de program
(BEGJ:N
.. .. ... o eventual secven de program care se execut
....... n momentul declarrl unitii de program n
....... programul care o utilizeaz.
END.]
procedura scad(a,brreal)t
begin
cra-b;
writoln(crls2);
end;
procedura produs(a,baroal);
bagin
caa*b;
writoln(cal:2);
end
procedura impart(a,brREAL);
begin
if b~ o thon writaln('~rtiroa nu se poate face ')
olso
begin
cra/b;
writoln(ca3a2);
endt
and;
begin
writo( 1 a 1 ) 1
roadln(a) ;
wri taln ( 1 b= 1 ) 1
roadln(b);
end.
~"'u al de informatic pentru clasa a Xl-a 43
..;; Funcia are un anumit tip, care precizeaz natura rezultatului. n exemplu,
tipul este doub:Le ntruct expresia calculat este de acest t\p.
-+ Funcia are variabile proprii - adica variabile care sunt definite n cadrul ei. n
exemplu, s i i. Aceste variabile se numesc variabile locale.
-+ Am vazut ntoarce un anumit rezultat - n exemplu, de tip double.
c funcia
Observai mecanismul prin care am obinut aceasta. Calculez expresia n
mod obinuit. Rezultatul este reinut de variabila local s. Prin instruciunea
"return s;", funcia a primit ca valoare de retur coninutul variabilei s.
La apel, lucrurile stau altfel: valorile acestora sunt cunoscute. Prin urmare,
acetia se numesc parametri efectivi.
#include <iostream.h>
void citeac(int vt[lO],int n)
{ int i1
for(i-=O;i<n;i++)
{ cout<<"v["<<i+l<<"l"l
cin>>vt[i];
}
}
main()
{ int v[lO),n;
cout<<n= ;
cin>>n;
citesc(v,n );
sortez(v,n );
scriu(v,n) 1
}
:> Cele trei funcii au tipul vo:l.d, adic nu au valoare de retur. Ele returneam
rezultatul prin intermediul parametrilor.
tip nume.
E:xemple de antete:
1
,
Observaii
test(2-3,2+3),
clasa de memorare;
vizibilitate;
durata de via;
tipul variabilei, singurul pe care l-am studiat pn n prezent.
Astfel avem:
int b;
main()
{ b 4;
cout<<a<<endl;
t(}J
}
3. Durata de via a variabilelor globale este static. Ele au spaiu rezervat n tot
timpul execuiei programului.
B} Variabile locale
Acestea sunt declarate n corpul funciilor. Mai precis, pot fi declarate n orice
bloc (instruciune compus) al acestora.
Exemplu:
void t()
{ int a3;
}
main()
{ int b4;
}
Exemplu:
register int b41
Exemplu:
void t()
{ int b4t
{ int c 3;
cout<<b<< " "<<c;
}
}
'Aanual de informatic pentru clasa a Xl-a 49
main()
{ a=S;
t();
cout<<a;
}
f , Observaii
./ n cazul n care, ntr-un anumit bloc sunt vizibile (se pot accesa) mai multe
variabile, toate cu acelai nume, dar au domenii de vizibilitate diferite, se
acceseaz variabila cu vizibilitatea cea mai mic. De exemplu, dac n
programul anterior se tiprete variabila a din cadrul subblocului funciei, se
tiprete 3, pentru c acesta este coninutul variabilei cu cea mai mic
vizibilitate (cea declarat n subblocul respectiv).
./ _!=xist posibilitatea ca, un ciclu for s conin~ declaraia unei variabile locale.
In secvena urmtoare se calculeaz suma primelor 4 numere naturale.
Variabila i este declarat (i n consecin vizibil) doar n blocul for:
3. Durata de via a variabilelor locale este att timp ct dureaz execuia blocului
respectiv.
<dz::. Privii programul urmtor. Acesta conine o funcie care calculeaz suma
~~ a dou numere naturale.
50 Capitolul 2. Subprograme
lat, de exemplu, cum sunt memorai n stiv parametrii n cazul primului apel:
stiva ---+1 2 1 3
a b
L Observaii
Exemplu:
#include <iostream.h>
void test (int n)
{ n+=l;
cout<<n<<endll
}
main()
{ int nl1
test (n);
cout<<n<<endl;
}
~ Apelm funcia. La apel, se rezerv spaiu n stiv, spaiu care are numele
parametrului (deci tot n) i este initializat cu valoarea memorat de variabila
n a programului principal. in acest 'moment avem dou variabile n i ambele
rein valoarea 1.
~ La ieirea din funcie, variabila n (din stiv) se pierde - adic nu mai are
spaiu alocat. Prin urmare, valoarea 2 este pierdut.
main()
{ test(3);
test(3+4*5);
}
main()
{ int a[lO];
vector(a)J
for (int iO;i<lOJi++) cout<<a(i)<<" "1
}
"'anual de informatic pentru clasa a Xl-a 53
#include <iostream.h>
void intersc(int &a,int &b)
{ int man=a;
a=b;
b=man;
}
main()
{ int x=2,:y=3;
intersc(x,y) 1
cout<<x<<" "<<y;
}
Dei aparent asem ntoare, cele dou noiuni difer . Buna nelegere a lor
-e ajut s evitm anumite erori. Mai mult, aceste noiuni sunt utilizate de orice
"'lbaj de programare, nu numai n C++.
void s2()
{ s1 (); cout<<"Eu sunt s2"<<endl;
}
main()
{ s1 () 1
s2();
#include <iostream.h>
void s2();
void sl()
{ s2 () 1 cout<<"Eu sunt sl"<<endl;
}
void s2()
{ cout<<"Eu sunt s2<<endl;
}
main()
{ sl ();
}
f
, (, l
Programatorii n C++ obinuiesc s scrie mai nti prototipurile tuturor
funciilorutilizate de program - fr main () - iar dup funcia ma in ( > s le
defineasc. n acest fel, orice funcie - mai puin ma in ( ) - poate fi apelat
din oricare alta:
#include <iostream.h>
void sl(); // prototip sl
void s2(); // prototip s2
main()
{ sl();
}
void al()
{ s2 (); cout<<"Eu sunt sl" <<endl;
}
void s2 ()
{ sl (); cout<<"Eu sunt s2"<<endl;
}
~an ual de informatic pentru clasa a Xl- a ss
::1 Aplicaia 2.1. Revenim la exemplul de funcie dat n paragraful 2.1. Acesta va fi
:-ezentat n totalitate. Se consider funcia:
x+ 1 , pentru xe [-1,1];
2
f(x)= ~-\, pentru xe(-oo,-1};
1 - -,
1 +X
pentru x e ( l , oo ).
~ Rezolvare. Cunoatei deja modul in care se calculeaza cel mai mare divizor
:omun pentru dou numere naturale date. Cel mai mic multiplu comun a dou
"Umere se poate determina imprind produsul lor la cel mal mare divizor comun al
or. Prin urmare, scriem o funcie cmmdc cu doi parametri formali m i n , care
.,toarce o valoare intreag- cel mai mare divizor comun al lor.
56 Capitolul 2. Subprograme
~Exerciii
1. Gs ii dou motive pentru care parametrii funciei cmmdc trebuie s fie transmii
prin valoare i nu prin referin.
2. Scriei
un subprogram cmmmo care s returneze cel mai mic multiplu comun a
dou numere naturale. Stabilii locul unde trebuie integrat acesta in programul dat
i modificai programul principal astfel fnct s se utilizeze subprogramul cerut.
3. Cte expresii diferite care au ca rezultat cel mai mare divizor comun al
numerelor naturale nenule a, b i o exist? ln orice expresie se utilizeaz numai
apeluri ale funciei ollDl\do i variabilele a, b i c. De exemplu, trei expresii sunt:
cmmdo(ommdc(a,b),c),
ommdc ( cmmdc (b, a), o) i
cmmdc(o,cmmdc(a,b) ).
~ Rezolvare. Dispunem deja de o funcie care calculeaz cel mai mare divizor
comun a dou numere i am testat-o n programul anterior. Pentru varietate, de
data aceasta implementm o funcie cu algoritmul lui Euclid pentru calculul celui
mai mare divizor comun, algoritm prin mpriri, nu prin scderi repetate. Cu
ajutorul ei calculm cel mai mare divizor comun pentru valorile reinute de primele
dou componente i memorm aceast valoare n variabila o. Apoi, pentru fiecare
dintre componentele urmtoare, se calculeaz cel mai mare divizor comun intre
valoare.a curent memorat in o i cea reinut de componenta curent a
vectorului. Cel mai mare divizor comun va fi reinut din nou de c.
Manual de informatic pentru clasa a Xl-a 57
~Exerciiu
In locul secvenei
c ~ cmmdc(v[ l) ,v[:ll))
pentru i =3, n execut
c ~ cmmdc(c ,v[i))
sfrtit pentru
dorim s utilizm, mal compact, secvena:
Care este valoarea pe care trebuie s o aib variabila c inaintea acestei secven~:?
1. m6 n1 2. m7 n9
1 9
2 3 l :Il
4 5 6 3 4 5
7 8 9 1 6 7 8 9
2 3 4 5 6 1 2 3 4 5
7 8 9 1 2 3 6 7 8 9 1 :Il
3 4 5 6 7 8 9 Junior Division
58 Capitolul 2. Subprograme
Alt aspect al problemei este realizarea tipririi acestor valori pe m linii, linia 1
avnd o singur valoare, linia a doua dou valori etc. Algoritmul este implementat
n procedura tipar, care are ca parametri formali pe m i n, transmii prin valoare.
Valorile lor sunt citite n programul principal.
~ Exerciii
1. Dup apelul tipar(mln) din programul principal, dac se adaug o instruc-
iune care afieaz valoarea lui n, ce valoare estimai c se va tipri?
2. Cum trebuie s arate definiia subprogramului suc, dac n subprogramul
tipar, n loc de n~suc (n), se utilizeaz instruciunea suc (n)?
3. Cum putem defini subprogramul suc astfel nct secvena de afiare din
subprogramul tipar s fie:
pentru i=l,m execut
pentru j=1,i execut
scrie suc(n)
sfrit pentru
scrie EOLN
sfrit pentru
V anual de informatic pentru clasa a Xl-a 59
:J Aplicaia 2.5. Se citesc dou numere naturale m<n. Se cere s' se tipreasc
~te
numerele palindrom aflate ntre m i n. Un numr este paling;om dac, citit de
r- stnga la dreapta
i citit de la dreapta ctre stnga, rezultatul este acelai. De
~em plu, numrull2l este palindrom.
Care este avantajul scrierii fiecrei funcii? Acesta este dat de faptul c,
s:unci cnd scriem funcia, ne concentrm exclusiv asupra ei, deci posibilitatea de
s g rei este mai mic . Dac dispunem de funcie, algoritmul in continuare devine
1ult mai simplu. n plus, este posibil ca oricare dintre funcii s poat fi folosit i n
3 te cazuri, la rezolvarea altor probleme.
f Observaii
"' Ordinea definirii celor dou subprograme devine important, deoarece funcia
in~ers, de care are nevoie funcia palin, trebuie declarat anterior acesteia.
/ Exerciii
1. Modificai antetul funciei invers, transformnd parametrul n n parametru
transmis prin referin i urmrii efectele modificrii efectuate.
.Junior Divlslon
0 Rezolvare. Suma cuburilor cifrelor unui numr natural este calculat de funcia
swna. Numrul n (citit) va ri memorat de prima compon ent a vectorului seria.
Apoi, suma cuburilor sale, de componenta a doua, suma cuburilor numrului reinut
de a doua component va fi reinut de a treia component, .a.m.d. Dup ce este
memorat o valoare, ea este comparat, pe rnd, cu cele obinute anterior. Dac
este regsit, se tiprete numrul de termeni ai seriei i seria propriu-zis
Funcia swna calculeaz suma cuburilor cifrelor unui numr. Funcia este verific
dac valoarea n exist deja n irul s format din ls componente.
l.lanual de informatic pentru clasa a Xl-a 61
3 4
3 1 7 g
1 2 3 4
9 1 3 8
62 Capitolul 2. Subprograme
Probleme propuse
a) G(x) =sin(x)+cos(x)cos(2x);
b) H(x) = 10{x} (am notat prin {x} partea fracionar a lui x).
'anual de informatic pentru clasa a Xl-a 63
7.Scriei o funcie care returneaz prima cifr a unui .,numr natural. De exemplu,
dac parametrul efectiv este 127, funcia va returna 1.
11
11. S se tipreasc toate numerele prime aflate ntre doi ntregi citii. Programul
va folosi o funcie care testeaz dac un numr este prim sau nu.
12. Scriei un program care tiprete numerele ntregi gsite ntre dou valori citite,
numere. care se divid cu suma cifrelor lor. Programul va utiliza o funcie care
returneaz suma cifrelor unui numr ntreg primit ca parametr.u .
13. S se scrie o procedur care permut dou linii date ale unei matrice ptratice.
14. Scrie! o procedur care interclaseaz doi vectori sortai tiind c acetia sunt
ordonai descresctor.
1
232
34543
4567654
567898765
67890109876
7890123210987
Junior Division
_-_a. de informatic pentru clasa a Xl-a 65
~ 6 6; b) 5 6; c) 6 6; d) 6 s.
:~ . Ce afi eaz programul urmtor?
o!j'! '., ' ' 1"
.~ Varianta Pascal ' Varianta C++'
function f(x:intege r):integer ; #include <iostream. h>
begin int f(int x)
f:=x+l { return x+1;
and; }
procedura t(a:intege r); void t(int a)
begin { a++; cout<<a;
a:=a+l; writeln(a) ; }
and;
void main()
begin { t(f(f(f(1) )));
t(f(f(f(l) ))) }
end.
a) 3; b) 4; d) eroare de sintax.
22. tiind c valorile citite ale variabilelor a i b sunt numere naturale nenule, care
dintre secvene utilizeaz subprogramul increment...pentru a obine produsul celor
dou numere?
writeln(t) cout<<t;
end. }
23. Pentru varianta de limbaj preferat, stabilii care dintre urmtoarele antete de
subprogram sunt corecte:
a) procedura p(n:integer; var void p(int n, int& v[10))
v: array[l. .101 of integer);
b) function p(n:integer;var p(int n, float& v)
v:real);
c) procedura p(n:integer;v:real); void p(int n, float v)
d) functio~ p(n):integer; int p(int& n; float v)
24. Pentru funciile definite mai jos, care dintre afirmaii este fals?
varianta Pascal
~ction Cat(n1,n2:in teger): long Cat(int n1,int n2)
longint; { int inv=O;
Tar inv:integer; while (n21a0)
~gin { inv=inv*10+n2 %10;
inv:=O; n2=n2/10;
while n2<>0 do begin }
inv:inv*10+ n2 mod 10; while (invi=O)
n2:=n2 div 10 { nl=nl*lO+inv% 10;
end; inv=inv/10;
while inv<>O do begin
n1:=n1*10+in v mod 10; return nl;
inv:inv div 10
end;
Cat:=nl
end;
26. Fiind dat funcia urmtoare, care dintre afirmaii este fals?
1'',__. ;.,:
;, ,,
' "':\ Varianta Pa9cal
.
type vect=array [1 40] of byte; void Concat(int A[20], int 1
8(20], int m, int n, int C[40],
procedura Concat(A,B :vect; int&. p)
m,n:b.yte;v ar C1vect;var p:byte);
void Reun(int A[20], int 8[20],
procedura Reun(A,B:v ect; int m, int n, int C[40], int&
m,n:b.yte;v ar C:vect;var p:b.yte); p)
n care:
Concat(X,Y,a,b, Z , p);
Elimin(Z,p);
Elimin(X,a); Elimin(Y,b);
Concat(X,Y,a,b,Z,p);
Elimin(Concat(X,Y,a,b ,Z,p),p);
Elimin(X,a); Elimin(Y,b);
Reun(X,Y,a,b,Z,p);
Inters (X,Y,a,b,Z,p)l
Dif(X, Z,a,p,Z,p);
= Inters( X,Y,a,b,Z,p);
Dif(Y,Z,b,p,Z,p)l
: Inters(Y, X,a,b,Z,p);
Dif(X,Z,a,b,Z,p);
~ Dif(X,Y,a,b,Z,p);
C. Dac n20, eate spaii se scriu naintea primului caracter"*", pe penultimul rnd?
A. Care este coninutul lui v dup apel, dac inainte este V=< 1, 2, 3, 4)?
a) V=(1 1 2,3 1 4); b) V=(4,3,2 1 1);
c) V=(0,1,6,10 ) ; d) V=(0,4 , 5 1 9) .
B. Care trebuie s fie iniial coni nutul lui v, dac dup apel este V= ( 1 1 6 1 10, o)?
a) V=(2,4,6,8); b) V=(1,6,10,0) ;
c) V=(0,10,6,1); d) V=(1,9,3,2) .
C. Pentru care dintre exemplele u rmtoare de configu raii ale lui v la intrarea n
subprogram, coni n utu l acestuia la i eire coincide cu cel de la intrare?
a) V=(13,10,5, 1 1); b) V=(2,3 1 9 1 13);
c) V=(0,1,2,12); d) v .. (1,4,9,15 .
'.1anual de informatic pentru clasa a Xl- a 71
a) 3; b) s;
c) nu exist o astfel de valoare; d) 2 .
C. Pentru X=< 1, O. O,
s , 7), Y= c1, 2, 7), stabilii ce valori pot fi scrise n casete
astfel nct apelul CJl\P ( 4, 4, x, Y) s returneze aceeai valoare ca i apelul
cmp ( 4 , 4 , Y, X) .
a) 2 i respectiv 3; b) 2 i respectiv s;
c) nu exist astfel de valori; d) 3 i respectiv 6.
O. Pentru care ir de vectori, funcia Cmp, apelat pentru oricare doi vectori
consecutivi n ir, returneaz aceeai valoare?
a) A= ( 1, 2, 3) , B= ( 1, 2, 3), C ( 1, 2, 2);
b) A=(1,2), B=(1,2), C=(1,3);
c) A=(1,3), B=(l,2), C=(1,3);
d) Ac ( 2), B= ( 1), c= (O).
72 Capitolul 2. Subprograme
Rspunsuri
19. d); 20. c); 21. a); 22. b); 23. c); 24. d); 25. b),c); 26.a) ;
29. Indicaie: fiecare numr este scris in binar pe o linie a matricei. Se afieaz
numerele zecimale obinute din numerele iri binar de pe fiecare coloan a matricei.
A. c) , B. a) , C. a) .
30. Indicaie: funcia realizeaz compararea lexicografic a doi vectori care rein
numere naturale. A. a) o; b) -1; c) 1; d) o; B. c); C. b); O. d).
Capitolul 3
iruri de caractere
. 1. Generaliti
-t Cine n-a folosit un editor de texte? Chiar acum, cnd scriem programele
Pascal sau C++ utilizm un editor de texte. Luai codul surs al unui program
(fiiere cu extensii .pas sau cpp). Observai c sursa este un fiier text n
care fiecare linie a ei, este o linie a fiierului text. Prin urmare, fiecare linie a
fiierului text conine un ir de caractere. Ce operaii putem face cu
editoarele? De exemplu, putem modifica o linie. O astfel de operaie const
n includerea sau tergerea unui subir (caractere consecutive din Interiorul
unul ir). Astfel de operaii se fac, i vom vedea cum, prin prelucrarea
irurilor de caractere. Alte operaii: a) Find- este o operaie de Identificare
a unui subir n cadrul unui ir de caractere; b) Replace este o operaie de
nlocuire a unui subir cu un altul; c) cut este o operaie prin care, din cadrul
unul ir se extrage un subir al su i acesta este memorat n Clipboard.
Prin Paste se insereaz un ir de caractere n cadrul altui ir de caractere.
irul exemplelor ar putea continua. Putei gsi altele?
t[S]
1-----l
- ...- . . - -..- t[255]
t[O] t[l] t[2] t[3] t[4] t[S] t[6] t[7]
n exemplul dat, irul 'I epuras este alctuit din apte caractere. Octeii de
a 11a 7 memoreatil caracterele din care este alctuit iru l. Restul octeilor, de la a
a 255 au un coninut neprecizat. De altfel, nici nu ne intereseaz coninutul lor.
faptul c afiarea s-a realizat, n ansamblu, prin precizarea numelui.
Observai
Mai mult, putem modifica coninutul unui singur octet, aa cum rezult din
programul urmtor.
var t: string;
begin
t 1 ':Iepuras;
t[6] 1'11 ' i ' l
write(t)J
end.
in urma atribuirii, variabila z reine cuvntu l" ~epuras" i acesta este afiat.
76 Capitolul 3 - iruri de caractere
Exemplu: v ar t: string[4];
Variabila t, ocup 5 oc:tei. Primul, cel de indice o, are rolul de a reine
lungimea cuvntului memorat. In acest caz, variabila poate reine cuvinte ce au cel
mult 4 caractere. Programul afieaz 'mama'.
var tt string[4 ] ;
begin
t z 'mama';
write(t);
end.
Exemplu:
var tz string[4];
t:= 'DANSATOR';
Exemplu:
var numet string;
Definiia 3.2. Concatenarea este operaia prin care din dou iruri de
caractere se obine un al treilea, format astfel: p~imul ir (cel aflat n
stnga operatorului), urmat de al doilea ir (cel aflat in dreapta
operatorului).
:.amplu:
program st6;
var t, z: string;
begin
t := acest';
z := ' exemplu';
t : t+z;
writeln(t);
end.
J Observaii
dac codul primului caracter al irului a este mai mare dect codul
primului caracter al irului b , atunci a>b.
dac codul primului caracter al irului b este mai mare dect codul
primului caracter al irului a, atunci a<b (b>a ).
Exemple:
a=' abc' , b= 'bactr . Atunci a<b, pentru c a [ 11 este a i are codul mai
mic dect b [ 1 1 care este b .
a= 1 abc 1 , b= aba 1 Atunci a>b, codul lui a [1] este egal cu codul lui b [1] ,
codul lui a [ 2 J este egal cu codul lui b [ 21 iar codul lui a [ 3 1 este mai mare
1
a abc' 1 b= 1 abea . Aici m=3, n=4. Atunci a<b, codul lui a [1] este egal cu
codul lui b [11. codul lui a [2 1 este egal cu codul lui b [2], codul lui a [3 ]
este egal cu codul lui b[3] i n>m (irul bare mai multe caractere).
Algoritmul de sortare este unul studiat (care?), motiv pentru care nu revenim
asupra lui. Programul este prezentat n continuare:
Exemple:
iru l mama are lungimea 4;
4 Exemple de utilizare
a) var a: string;
c: integer;
a := un test ' ;
c := length(a);
2. Dup
cum am nvat, octetul de indice o reine lungimea irului. Pentru c
obinefolosim funcia ord astfel: ord(a [01 >. De ce aa? Atunci cnd scne-
a[OJ ne referim la un caracter. Folosind aceast expresie obinem caracterul ca
are codul dat de numr (n binar). Deci, pentru a obine codul su, utiliz~
funcia ord.
var a: string;
begin
write('a= '); readln(a);
writeln('lungime a sirului a este ' length(a))t
writeln('lungime a sirului a este ord(a[O)));
end.
Un caz aparte de ir este irul vid. Prin ir vid nelegem un ir f/!1r nici ...
caracter. Evident, irul vid are lungimea o.
Exemple:
irul harnic are ca subir irul mi . Acesta ncepe n poziia a treia din
irul iniial (3 caractere);
irul harnic nu are ca subir irul rnit , chiar dac primele trei
caractere (mi) se regsesc n irul iniial.
'Mual de informatic pentru clasa a Xl-a 81
,. Funcia copy are rolul de a extrage un subir din cadrul unui ir dat:
function copy(s:string;inceput,lungime:integer):string;
variabila s (de tip string)- conine irul din care se face extragerea;
inceput - reine poziia de nceput a subi rului care se extrage;
lungime - rei ne numrul de caractere care se extrag.
var a, b: string;
i, j: byte;
begin
write('a= ') ; readln(a);
write('i= '); readln(i);
write('j= '); readln(j);
b := copy(a, i, j);
writeln(b);
end.
)- Funcia pos are rolul de a verifica dac un ir este subir pentru altul:
function pos(subsir,sir:string):byte;
F uncia returneaz:
Exemple: 1. Fie irul abcde 1 Se caut subirul 1 bcd 1 Acesta este gsit, iar
1
2. Programul urmtor citete dou iruri a i b i verific dac b este subir al lui
a. n ambele cazuri se dau mesaje. Dac b nu a fost identificat ca subir al lui a,
sau, n caz contrar, se afieaz poziia de nceput a sa.
var a, b: string;
n: integer1
begin
write('a= '); readln(a);
write('b ')1 readln(b)J
n := poa(b,a);
if n O then writeln('b nu este subsir al lui a')
else writeln('b este subsir al lui a si incepe in
pozitia ,n) 1
end.
Exemplu:
var a, b: string;
begin
write(a '); raadln(a)t
write('b '); readln(b)t
insert(b, a, 3);
writeln(a);
and .
)o> Procedura delete are rolul de a terge un subir din cadrul unui ir dat.
Pentru aceasta, ea are ca parametri, n ordine:
procedure delete(var sir: string; indice, nr_car: integer);
unde:
::Xemplu:
Programul urmtor citete un ir de caractere ntr-o varibil de tip string,
- -it a. irului cititi se terge subirul care ncepe n poziia 3 i are lungimea 2
::ou caractere). De exemplu, dac variabila a reine irul abcde', se afieaz
.aba'.
var a:string1
begin
write('a= ' ); readln(a)J
delete(a,3,2);
writel n(a);
end.
O Aplicaia 3.2. tergerea tuturor apariiilor unui subir din cadrul unui ir:
var sir., subsir: stringi
poz, lung: byte1
begin
writeln(introduceti sirul')l readln(sir);
writeln('introduceti subsirul '); readln(subsir)J
lung:~ length(subsir);
poz : pos(subsir, sir);
while poz <> O do
begin
delete(sir, poz, lung);
poz := pos(subsir, sir);
end;
writeln(sir)J
end.
84 Capitolul 3 - iruri de caractere
O Aplicaia 3.3. nlocuirea tuturor apariiilor unui subir cu alt subir. Analizai
programul urmtor pentru a descoperi modul n care se realizeaz aceasta:
var sir, sir_ sters, sir_adaugat: string;
poz, lungt byte;
begin
writeln( 1 introduceti sirul 1 ) ; readln(sir);
writeln( 1 introduceti sirul care se sterge);
readln(sir_sters);
writeln( 1 introduceti sirul care se adauga)/
readln(sir_ adaugat)J
lung := length(sir_sters);
poz : pos(sir_sters, sir);
while poz <> O do
begin
delete(sir,poz,lung);
insert(sir_adaugat, sir, poz);
poz t= pos(sir_ sters, sir);
end1
writeln(sir};
end.
Exemplu:
var a: string1
n: integer;
begin
write ( 1 n '); readln(n);
str(n, a);
writeln(a)
end.
};> Pentru realizarea conversiei utilizm procedura val. Ea are trei parametri i
anume:
proc:edu.re val (a: atring1 var variabila...JNIIIB%'ica; var cod._er: integer) ;
unde:
a - conine irul ce urmeaz a fi convertit;
var as stringi
x, ers integer;
begin
write('Sirul este ')1 readln( a)l
val(a, x, er)1
if er O then writeln(' conversia a reusit , x)
el se
begin
writeln ('conversia nu a reusit')/
writeln(x)
end
end.
Observaii
Dac irul de caractere cifre este precedat de un numr de blank-uri,
conversia reuete.
Exemplu: irul 1
123 1 se poate converti ctre valoarea 123.
Dac variabila care reine rezultatul este de tip ntreg, iar irul conine punctul
zecimal, conversia nu reuete.
Programul de mai jos demonstreaz acest fapt (dac linia 1 a fiierului are 3
caractere, se vor afia dou pe un rnd i unul pe al doilea rnd). Dup citirea unei
astfel de variabile, pointerul se afl sau pe caracterul ce urmeaz dup ultimul
caracter citit sau pe CR. n situaia n care pointerul se afl pe CR i se foreaz o
nou citire de tip String, se returneaz irul vid.
var f: text;
a: string[2];
b: string;
begin
assign(f, 'fl.dat');
reset(f);
read(f, a);
writeln(a);
read(f,b);
writeln(b);
close(f);
end.
3.3.1. Generaliti
1 c 1 a 1 1 1 c 1u , ........................................................................................, J
O
Exemple:
char vect(ll]="calculator".
char vect {] "calculator". n acest caz, compilatorul face calculul
numrului de octei necesari.
char vect [100]a"calculator". Am rezervat mai muli octei dect era
necesar.
#include <iostream.h>
main()
{
char a[20];
cin>>a;
cout<<a;
}
J~ Observaii
./ Caracterul nul este adugat automat.
Exemplu: a [O]= 1 c 1
, a [1) =a 1
, .a.m.d.
Din pcate, prin metoda de mai sus nu poate fi citit un ir care conine mai
multe cuvinte separate prin spaii. De exemplu, dac la rularea programului anterior
tastm irul" un om", se va afia "un". Aceasta nseamn c citirea se face astfel:
Din acest motiv, pentru citirea irurilor de caractere vom utiliza o funcie de
un tip special, pe care o prezentm n continuare.
)> Funcia:
Observaii
sau cnd
2.. _a fel ca mai sus, dar citirea se ntrerupe la ntlnirea caracterului
1
1 g
n C++ pot exista mal multe funcii cu acelai nume, dar care difer
prin
::.arametrii primii. Astfel, exist i funcia:
ain.ge t()
~r parametri. Ea are rolul de a citi un caracter (fie c este alb, fie c nu).
#include <iostream.h>
main()
{
char a[]a"masa";
cout<<a+l<<" "<<a+2<<" "<<a+3;
Din acest motiv, programul ti prete pentru a+l irul "asa" , pentru a+2
irul "sa", .a . m . d . Mai mult, vectorii astfel adresai pot fi accesa i aa cum
suntem deja obinuii. Astfel, pentru exemplul anterior, (a+l) [OJ reine caracterul
'a' , (a+l) [1] reinecaracterul s ,etc.
Dup cum observai, a+l, a+2, ... sunt expresii. Orice expresie are un
anumit tip. Care este tipul lor? Tipul acestor expresii este char*. Ce semnificaie
are? Semnificaia este cea de adres.
#include <iostream.h>
main()
( char a[]"Exemplu", *p;
paa; cout<<p<<endl;
p++; cout<<p<<endl;
p++l cout<<p<<endl;
cout<<p[ll<<endl;
cout<<p-a;
}
#include <iostream.h>
#include <string.h>
main()
{ char a[lOOJ;
cin . get(a,lOO) ;
cout<<"Sirul citit are "<<strlen (a)<<" caractere";
}
Aa cum tim din lucrul cu tablouri, atribuirile de forma ab, unde a i b sunt
vectori de caractere, nu sunt permise. Tot aa, o atribuire de forma a:::"un sir"
nu este permis. Astfel de operaii ca i multe altele se fac cu anumite funcii, puse
la dispoziie de limbaj. Pentru ca acestea s poat fi folosite, trebuie s fie inclus
fiierul antet "string. h", tot aa cum includem fiierul "iostream. h". Ordinea
de includere nu are importan. fn continuare, vom prezenta cele mai uzuale funcii
i modul fn care acestea se folosesc.
iare rolul de a copia irul de adres sursa la adresa dest. Copierea se termin
dup ce a fost copiat caracterul nul. Se returneaz adresa dest. Analizai
codul urmtor:
#include <iostream.h>
#include <string . h>
main()
{ char a[lOO]="un sir", b[lOO]"alt sir"t
strcpy (a,b);
cout<<at
}
i rolul de a aduga irului de adres dest irul de adres sursa. irul de adres
sursa rmne nemodificat. Aceast operaie se numete concatenare i nu este
comutativ. Rezultatul este adresa irului sursa, iar irul va avea ca lungime,
suma lungimilor celor dou iruri care au fost concatenate.
.,... Jal de informatic pentru clasa a Xl-a 95
r ace)al
ro) ca strcat cu deosebirea c adaug lru)u'l destma'le prlm'll nr octei al
s rului surs. Adugarea caracterelor se face Tnaintea caracterului nul. Funcia
-etu rneaz adresa de nceput a irului destinaie.
#include <iostream.h>
#include <string . h>
main()
{
char a[20]"Acesta este"1
cout<<strchr (a,'t 1 )1
}
Programul de mai jos tiprete indicele primei apariii a caracterului 't', i anume 4:
#include <iostream.h>
#include <string.h>
main()
{
char a[201="Acesta este";
cout<<strchr (a, t)-a;;
}
,Jw Observaii
../ Variabila t este de tipul char* .
#include <iostream.h>
#include <string.h>
main()
{
char a[lOO], *t,c;
cout<< "introduceti sirul "; cin.get(a, lOO);
cout<< "caracterul cutat "; cin>>c;
t=a-1;
do
(
t++;
t=strchr(t,c); .
if (t) cout<<"Indicele este "<<t-a<<endl;
} while (t);
}
Fiecare adres de subir, care are ca prim caracter cel reinut de c, intr n
calculul indicelui acelui caracter - din ea se scade adresa de nceput.
97
- 3. 7. Compararea irurilor
? Dar care este mecanismul prin care se compar dou iruri de caractere?
Fie m numrul de caractere al irului sl i n numrul de caractere al irului s2.
5 presupunem c primele i caractere ale lui sl coincid cu primele i ale lui s2.
:J n cazul n care codul caracterului i+l al iru l ui sl este mai mare dect codul
caracterului corespunztor irului s2, avem sl>s2.
:l n cazul' n care codul caracterului i+l al irului sl este mai mic dect codul
caracterului corespunztor irului s2, avem sl<s2. ln cazul in care i la
aceast comparaie avem egalitate, avem patru posibiliti:
ambele iruri au un numr strict mai mare de caractere dect i+l, caz n
care se compar ca nainte caracterele de pe poziia i+2;
. sl are i+l caractere, iar s2 are un numr de caractere mai mare dect
i+l, n acest caz sl<s2;
s2 are i+l caractere, iar sl are un numr de caractere mai mare decat
i+l, n acest caz sl>s2;
Exemple: "soare">s;
"tata">mama;
98 Capitolul 3 -iruri de caractere
(;, Funcia strcmp face distincie ntre literele mari i miel ale a/fabetului.
i acelai rol ca strcmp. Diferena este c nu face distincie ntre literele mari i
miel.
Vectori de cuvinte. Exist aplicaii in care este necesar s se lucreze cu n
cuvinte - fnelegnd prin cuvnt o succesiune de caractere care nu sunt albe. n
acest caz avem posibilitatea s declarm vectori de cuvinte. Acestea sunt, de fapt,
matrice cu elemente de baz de tip char.
Fiecare linie din cele 10 ale matricei poate reine un ir de caractere. Acesta poate
avea cel mult 25 de caractere (inclusiv caracterul nul). Cuvintele pot fi adresate prin
a [O] (primul cuvnt), a [1) cuvntul al doilea, . a . m . d.
do
{ gasit=O;
f or (i=O;i<n-l;i++)
if {strcmp(cuvinte[ i],cuvinte[i+l])>O )
{ strcpy(man,cuvin te[i]);
strcpy(cuvinte[i ],cuvinte(i+l]);
strcpy(cuvinte[i+ l],man);
gasit=l;
}
}
while (gasit);
for (i=O;i<n;i++) cout<<cuvinte[i ] <<endl;
Dac pot compara dou cuvinte, atunci pot s le sortez. Am folosit sortarea
nterschimbare. lat c, algoritmii, cu precdere cei fundamentali, pot fi folosii
"'tr-un context diferit de cel n care au fost prezentai.
3.8. Subiruri
#include <iostream.h>
#incl ude <string.h>
m.ain()
{
char sir(l000],subsir[ 25], *t;
cout<<"introduce ti textul ";
cin.get(sir,lOOO );
cin.get();
cout<<"introduce ti subsirul cautat ";
cin.get(subsir,2 5);
t=strstr(sir,sub sir);
if (t) cout<<"este subsir si are indicele "<<t-sir;
else cout<<"nu este subsir";
}
100 Capitolul 3- iruri de caracterE
O Aplicaia 3.10. tergerea tuturor apariiilor unui subir din cadrul unui ir
Imediat ce am identificat adresa de inceput a subiruloi, restul irului (fr subir)
este copiat pe poziia de inceput a subirului.
#include <iostream.h>
.# include <string . h>
main()
{ char sir[1000],subsir[ 25],*p;
int lung_subsir;
cout<<"introduce ti textul ";
cin.get(sir,1000 );
cin.get();
cout<<"introduce ti subsirul ";
cin.aetlBUbB~r,~~)i
lung_ subsir=strlen(su bsir);
pstrstr(sir,sub sir);
while (p)
{ strcpy(p,p+lung_ subsir);
p strstr(p,subsir) ;
)
cout<<sir;
)
O Aplicaia 3.11. fnlocuirea tuturor apariiilor unui subir cu alt subir. V las pe
dvs. s descoperii modul in care programul urmtor realizeaz aceasta:
#include <iostream.h>
#include <string.h>
main()
( char sir[100], man[100], sterg[25], ada ug[25], *p;
int lung_ sterg, lung_ adaug;
cout<<"introduce ti textul ";
cin.get(sir,lOO) ;
cin.get();
cout<<"inlocuim subsirul ";
cin.get(sterg,25 );
cin . get();
cout<<"cu subsirul "1
cin.get(ad&ug,25 );
lung_ sterg strlen(sterg);
lung_ adaugstrlen(ada ug);
pstrstr(sir,ste rg);
while (p)
(
man[O] O;//subsir vid;
strncat(man,sir, p-sir);
strcat(man,adaug );
strcat(man,p+lun g_ sterg);
atrcpy(sir,man);
pstrstr(p+lung_ adaug,sterg);
)
cout<<sir;
. )
a.~ual de Informatic pentru clasa a Xl-a 101
Exemplu: irul sl. este " mama, tata si bunicul". irul s2 este:
" , ". ntruct caracterele separatoare sunt blank-ul i virgula, rezult c
entitile sunt: ":mama", "tata" "si" "bunicul".
la prima apelare care trebuie s fie de forma strtok ( sl, s2) 1, funcia
intoarce adresa primului caracter al primei entiti (n exemplu "mama"). in
plus, dup prima entitate separatorul este nlocuit automat prin caracterul
nul (cod O);
urmtoarele apeluri ale funciei sunt de forma strtok (NULL, s2);, iar
funcia intoarce de fiecare dat adresa primului caracter al urmtoarei entiti
i , dup ea, este adugat caracterul nul - aceasta permite ca entitatea s
poat fi extras cu uurin.
Caut primul caracter al irului al n s2. Dac este gsit, returneaza adresa
sa din cadrul iru lui sl i execuia se termin, altfel trece la pasul urmtor.
Caut al doilea caracter al irului sl n s2. Dac este gsit, returneaz adresa
sa din cadrul irului sl i execuia se termin, altfel trece la pasul urmtor.
dac nici un caracter al irului al m:. aparine irului s2, funcia returneaz
adresa nul.
104 Capitolul 3 - iruri de caractef"!
~~ <iostream.h>
~:de <string.h>
~~e <stdlib.h>
IIIC..:::.
:.:.ar sir[lOOO],separator[]=" ",cifre[]="0123456789.+-", *p;
!.cx!b~ e s=O;
~ .get(sir,lOOO);
~st rtok(sir,separator);
~le (p)
i f (strspn(p,cifre)==strlen(p)) s+=atof(p);
p=strtok(NOLL, separator);
:::_... :":'<3 ecvt are rolul de a converti o valoare de tip double ctre un ir.
:..~e rul nul este adugat automat irului obinut. Forma general este:
~ ecvt(double valoare, int poz, int* zec, int* semn);
dac val reine 1234, atunci se returneaz irul "123", zec reine 4 i
semn reine o.
dac val reine 1239, atunci se returneaz irul "124", zec reine 4 i
semn reine o.
dac val reine 1, atunci se returneaz irul "100" , zec reine 1 i semn
reine o.
dac val reine -0.001, atunci se returneaz irul "100", zec reine -3
i semn reine 1.
)> Funcia itoa are rolul de a converti o valoare de tip int ntr-un ir, a crui
adres este memorat in variabila sir. Valoarea baza reine baza de numeraie
ctre care s se fac conversia (de obicei baza este 10). fn cazul bazei 10, irul
obinut reine i, eventual, semnul"-". Funcia ntoarce adresa irului obinut.
)> Funcia 1 toa are acelai efect ca i toa, deosebirea fiind dat de faptul c se
convertete ctre ir o valoare de tip long int.
)> Funcia ultoa are acelai efect ca itoa, deosebirea fiind dat de faptul c
se convertete ctre ir o valoare de tip unsigned long.
Funcia
, Funcia
, Funcia
Pentru a citi o linie a unui fiier text, se poate folosi funcia urmtoare:
Evident, n acest fel, la o citire pot fi aduse n memorie cel mult 32766
caractere (vezi limitele tipului int).
l~ Observaii
../ Caracterul care marcheaz sfritul liniei ' \n' nu este inserat n ir, n
schimb este inserat caracterul nul (march eaz sfritul iru lui) .
../ Este suficient s apelm funcia cu primii doi parametri, ultimul fiind implicit.
../ Dac se dorete, ultimul parametru poate fi apelat explicit cu o valoare
convenabil, caz Tn care citirea se face pn la intlnirea ei sau pn cnd
au fost citite Nr_car-1 caractere.
..11. Programulurmtor citete linie cu linie un fiier text ale crui linii nu au
~. mai mult de soo de caractere i afieaz liniile pe monitor. Nu se
cunoate lungimea fiecrei linii.
#include <fstream.h>
main()
{ fstream f("f.dat",iosz:in );
char Linie_citita[501 );
while (f.getline(Linie_ ci tita,501))
cout<<Linie_citit a<<endl;
}
Observaie foarte
(;. efectueaz
important! Prin fLinie_citito. , citirea se
astfel:
a) ncepnd cu poziia curent a pointerului se sar toate caracterele albe;
b) se citesc toate caracterele pn la ntlnirea unui caracter alb.
De exemplu, dac o linie a fiierului conine irul " Afara ploua", se
citete irul"Afara". Testa.i!
iX~ ~al de informatic pentru clasa a Xl-a 1os
#include <fstream.h>
main()
{ fstream f("f.dat",ios::out);
f<<" Afara este"<<endl;
f<<"primavaral";
f . close() 1
}
Un ir x
reine "1 2 3 4 5". O funcie special ( numit constructor)
.i:aeaz irului x , un stream (flux), numit ins. Ea are doi parametri: irul x i
.-gimea lui: istrstream ins (X, strlen (X)) 1.
#include <iostream.h>
#include <strstrea.h>
#include <string.h>
main()
{
char X[)="l mama tata 4 bunica";
char cuvant [20);
istrstream ins{X, strlen{X));
while (ins>>cuvant && strlen(cuvant))
cout<<cuvant<<en dl;
}
Probleme propuse
1. Se de la tastatur un text. Cuvintele se
citete consider separate prin virgul
spaiu sau punct. eate cuvinte are textul citit?
3. Se citete un text. Dou cuvinte pot fi separate printr-unul sau mai multe spai i
Se cere s se elimine spaiile inutile.
4. Se un fiier text care conine o singur propoziie, pe o linie. Programul
citete
rea ranjeaz literele n fiecare propoziie, in ordine alfabetic, pstrand locul
cuvintelor. Numai literele de la 'A' la 'Z' sunt afectate. Celelalte caractere rmn
neschimbate. Ieirea va fi tot un fiier text. Numele fiierelor este ales de dvs.
Exemple:
Junior Divislon
1
::.,ual de informatic pentru clasa a Xl- a
ea micorat a cuv
ntului "MISSISSIPPI",
ve rsi un
:.. Eli mi na re. "MSSSS
PP " es te micorat i ea :
uro r lite rel or "1". O fraz poate fi
:~n ut prin elimi
na rea tut RSR C FAT", prin
RA TE " are ve rsiunea micorat ''TRV
~AVERSAREA CA
II FE ne literele dintr-o
"E" . Se ce re ca programul dvs. s elimi se
= 11inarea literelor "A ", "1", linie. Literele care
t np ut . tx t" i scris pe o singur
ul "i
-az citit din fiier
tex t .tx t" .
este n fiierul "o ut pu
:m in se citesc de
la tastatur, iar ieirea
Ju nio r Di vls ion
z lim ba jul
co lec tiv - nu ma i pe ntr u ele vii care studia
n
- Problem de luc ru
l. ir uri ge ne ral iza te.
:~asca re
um ii de faptul c,
in Pascal, irurile cu ca
sun te i mul
Presupunem c nu
caractere.
~e poate lucra po t
avea cel mult 25 5 de
caractere.
luc rm cu iruri care
au cel mu lt 30 00 de
De exemplu , do rim s
iar sfritul unui ir
re inu t ca un ve cto r de 30 00 de caractere,
Jn astfel de ir va fi
valorii o (in binar).
:a fi marcat prin memorarea
subprogramele urmtoare:
Scriei
ir ;
in lungimea unui
subprogram care determ
iruri ;
ite concatenarea a dou
subprogram ca re perm
ir pentru altul;
ir este sau nu sub
bp rog ram ca re identific dac un
su
tete un ir ctre
un int reg;
subprogram care conver
re un ir;
tete un intreg ct
subprogram care conver
tete un ir ctre
un numr rea l;
subprogram care conver
tete un real ctre
un ir;
subprogram care conver
anumit poziie a
altui ir ;
rog ram ca re ins ereaz un ir pe o
subp
ate poziia
re terge un subir
al unui i r da t (se cuno
su bp rog ram ca
;
de inc ep ut a subirului)
intr-un fiier tex t;
su bp rog ram ca re permite sc rierea unui ir
n fiier text.
ite citirea unui ir dintr-u
subprogram care perm
Capitolul 4
Structuri de date neomogene
f Observaii
.- "
~ual de informatic pentru clasa a Xl-a
115
Aa cum s-a artat, elementele unui vector pot fi de orice tip, deci inclusiv
tip RECORD.
Adresarea cmpurilor se face prin numele vectorului, urmat
de perechea de
ranteze drepte ntre care este trecut indicele compo
nentei, apoi selecia
~ ri u-zis se face aa cum am nvat.
1 Limbajul permite ca
realizeaz aceasta?
nregistrrile s aib o structur variabil. Cum se
f Observaii
n C++ exist un tip de date, numit atruot, care ne permite acest lucru.
Forma general este (ce este trecut ntre paranteze drepte este considerat facultativ):
struct [nume structura]
{
[<tip> <nume variabila[, nume variabila, ]>]
[<tip> <nume variabila[, nume variabila, ]>] 1
} [lista de variabile] 1
i se numete elev.
IJan ual de informatic pentru clasa a Xl-a
119
Exi st dou posibiliti de dec lara re a vari abil elor care _alc
tuiesc structura.
1. Aa cum rezult din form a general, scriind la sfrit numele variabilelor:
stru ct ele v
{ cha r num e[20 ], pren ume [20]
;
floa t nota _ma te,n ota_ info ;
int var sta1
}in r1,i nr2 ;
mai n()
{ ele v inr1
cout <<"N Ume "1 cin> >inr .num
e;
cou t<< Pren ume "1 cin> >inr .pre
num e1
oou t<< "No ta mat ema tica ";
cin>>inr.nota~te;
cou t<< No ta info rma tica "1
cin> >in r.no ta_i nfo ;
oou t<< "Va rsta "1
cin> >in r.va rsta 1
cout <<" Am oit it t << end l
<<in r.nu me< <" "<< inr. pren ume
<<e ndl
<<inr.nota~te~<endl
<<i nr.n ota_ info <<e ndl
<<i nr . var sta;
}
120 Capitolul 4. Structuri de date neomogene
ntre dou variabile de acelai tip struct se poate folosi atribuirea. Astfel,
dac inrl, inr2 sunt dou variabile de tip elev, prin atribuirea inrl:::inr2,
variabila inrl ia aceeai valoare ca variabila inr2. n C++, o astfel de atribuire se
mai numete copiere bit cu bit.
struct elev
( char nume(20], prenume[20];
struct
( int clasa;
float note(20] ;
}situatie;
int varsta;
} ;
l't .,. Fie inr o inregistrare de tipul elev. n aceste condiii, accesarea
Q %: 1
elementelor situate n interiorul substructurll se face ca mai jos:
struct elevl
( char nume[20], prenume[20);
struct
( int clasa;
float note[20);
}situatie_ l, situatie_2;
int varsta;
};
} [lista de variabile] ;
main()
{ persoana pers;
cout<<"Nume persoana " ;cin.get(pers . nume,30);
cout<<"Studii f-fara g-generala,l-liceu;s-superioare) ";
cin>>pers.studii;
switch (pers.studii)
{
case g : cout<<" numar clase" ;
cin>>pers.std . nr_clase;
break;
case '1': cout<<"anul terminarii liceului" ;
cin>>pers.std . liceu.an_t;
cout<<"orasul ";
cin>>pers.std.liceu.oras;
break;
case s: cout <<"nwnele facultatii ";cin.get();
cin.get(pers.std.facultate.nume_f,30);
cout<<"nr ani de studiu ";
cin>>pers.std . facultate.nr_ani;
}
~ anual de informatic pentru clasa a Xl-a 123
//afisez inregistrarea
cout<<pers.nume<<endl;
switch (pers . studii)
{
case 'f': cout<<n-are saracu studii"; break;
case 'g': cout<<" numar clase "<<pers.std.nr_clase; break;
case '1': cout<<"a terminat liceul in"
<<pers.std.liceu.an_t
<<" in orasul "<<pers . std.liceu.oras; break;
case s: cout<<"numele facultatii"
<<pers.std.facultate.nume_f
<<" nr ani de studiu "
<< pers.std.facultate.nr_ani;
}
}
Probleme propuse
1. Citii o variabil cu urmtoarea structur:
nwne_elev: 30 caractere;
data_nasterii:
zi : intreg;
luna : intreg;
an : intreg;
nota matematica - real;
nota informatica - real;
nota engleza - real;
media - real;
Testai dac datele au fost introduse corect. Citirea se va verifica prin afiarea
rezultatului.
2. Citii n nregistrri de tipul celei de mai sus i afiai-le n ordinea alfabetic a
numelui.
o mulime de valori;
o regul de codificare a acestora; 1
o mulime de operaii definite pe mulimea datelor.
Prin tipul de mai sus se descrie structura unei variabile capabil s rein
numere raionale. Fie A 1 mulimea valorilor care pot fi memorate prin utilizarea
tipului ntreg. Fie A2 =A1 {0}. Atunci, o variabil de tip ratio nal poate memora
valori care aparin mulimii A 1 XA2 Evident, este sarcina programatorului ca valoarea
reinut de variabila corespunztoare lui q s fie diferit de o.
n unele lucrri vei ntlni definiii ale tipului de date care exclud regula de codificare. Aici
1
Fie B mu limea valorilor care pot fi reinute de tipul real. Atunci, variabila a
poate reine la un moment dat un element al mulimii :
BxBx ... x B.
~
de 11 an'
Practica impune utilizarea unor structuri ale datelor de o mare varietate, care
nu se suprapun ntotdeauna peste tipurile care pot fi descrise prin limbaj .
Vom numi nod, o variabil de un tip oarecare. De obicei, acest tip este
structurat. Dup caz, termenul nod poate fi nlocuit cu articol, nregistrare sau
entitate.
fn cele mai multe cazuri, "ansamblul de date" care formeaz structura este
alctuit dintr-o mu lime cu un numr variabil de noduri.
Relaiile existente Tntre noduri i operaiile care pot fi efectuate cu ele vor fi
prezentate prin exemple.
IH: De reinut!
fJ
./ ln practic s-au impus anumite structuri. Acest lucru este datorat faptului c
exist muli algoritmi care le utilizeaz. Ele vor fi tratate, pe scurt, n
paragrafele urmtoare.
126 Capitolul 5. Structuri de date
Definiia 5.2. O list liniar este o colecie de n~O noduri, x1, xl, ... , Xn
aflate ntr-o relaie de ordine. Astfel, X 1 este primul nod al listei, X 2
este al doilea nod al listei, ..., Xn este ultimul nod.
a) Evidena situaiei colare a elevilor unei clase. Fie n numrul elevilor. Aici, un
nod reine numele unui elev i notele la diversele materii. Vom avea deci, n noduri.
Nodurile vor fi memorate in ordinea alfabetic a numelor elevilor. n clasa
respectiv pot fi transferai elevi din alte clase, caz in care se adaug noduri. Din
clas, unii elevi pot pleca n alte clase, caz in care se terg noduri.
a) Accesul la oricare nod al listei se poate face cu mare uurin . Dac dorim s
adresm nodul k, atunci scriem v [kl (presupunand c vectorul care reine nodul
se numete v).
1 71 1 1 12 1 8 1 9 15 1 8 13 12 1 6 +. . . . .f...........
f...........l.......... I........... +. . . . . +. . . J
J......... I..........
1 71 3 1 1 1 2 1 8 19 1 5 18 1 3 1 2 1 6 1
128 Capitolul 5. Structuri de date
111 13 11 12 la 19 15 la 13 12 16 1
Acum se completeaz valoarea reinut de nodul 2:
171 5 1 3 11 12 1a 19 15 18 13 12 16 1
Observaii
adr1
.J.I..:..ad.::.:.r:...dt---~11!
Ll..:.in:.:..
1
adr2
1 in2 1adrd .. nil
in1, in:l, ... , inn reprezint informaiile coninute de noduri, de alt natur
dect cele de adres.
1 nil 1in 1 1 adr2 1 1 adr1 1 in2 1 adr3 C: ::::J adrn11 inn 1 nil
adG ad~ adrn
Aa cum am invat, lista liniar este alctuit din mai multe noduri intre care
exist o relaie de ordine. Tn cazul alocrii Tnlnuite, informaia memorat de
ecare nod va cuprinde i un cmp de adres -in cazul alocrii simplu inlnuit
sau dou cmpuri de adres -in cazul alocrii dublu Tn lnuit. in acest paragraf
vom studia implementarea alocrii simplu in lnuit.
lat cum se descrie informaia dintr-un nod, n cazul listelor alocate simplu
nlnuit, atunci cnd acesta reine un nu[llr intreg.
Pentru memorarea listei folosim un vector care are componentele de tip Nod,
descris mai jos:
Varianta C++
Lista=array[l lOOO) of Nod; nod L[1000];
var L:lista~
Din descriere rezult c lista poate avea cel mult 1000 de noduri. Acesta
este spaiul disponibil.
L ~~~-7~-3--~--~--_.-5~~4--~~--5--~4~--o--~~~~
1 2 3 4 5 6
130 Capitolul 5. Structuri de date
1~~.~ J I o
.~rJ. Ce observm?
a) Fiecare nod trebuie s rein i adresa nodului urmtor. Adresa este, de fapt,
indicele componentei din vector care reine informaia asociat nodului urmtor.
Prin urmare, necesarul de memorie este mai mare.
L ----.1 3 15 1 11
4 1 5 14
1 2 3 4 5 6
ocupat-.! o o
1 2 3 4 5 6
L ... 1 7 13 15 14 11 15 4 1o
1 2 3 4 5 6
ocupat---.1 o o
1 2 3 4 5 6
b) Memorm informaia: 9.
L~1713 Q 15 14 11 5 14 1 o
1 2 3 4 5 6
ocupat---.1 o
1 2 3 4 5 6
L ... 1 7 1 3 Q !1 5 14 1 1 15 14 1 o
1 2 3 4 5 6
ocupat---.1 o
1 2 3 4 5 6
L ... 1 7 1 3 Q fi 1 5 14 1 1 12 14 1o
1 2 3 4 5 6
ocupat---.1 o
1 2 3 4 5 6
[8] Problema 4. tergerea unui nod. sa presupunem c in lista de mai jos dorim
s tergem al doilea nod.
L ---+1 1 7 3 15 14 11 1 5 14 1o
1 2 3 4 5 6
ocupat--+-1 o o
1 2 3 4 5 6
L 1 7 14 15 1 4 11 1 5 14 1o
1 2 3 4 5 6
ocupat--+-1 o o o
1 2 3 4 5 G
Lista va deveni:
Exemplele sunt date pentru lista liniar simplu nlnuit, dar bine nelese,
ne permit s deducem singuri modul de efectuare a operaiilor respective pentru
liste dublu nlnuite .
"'an ual de informatic pentru clasa a Xl-a 133
Definiia 5.3. Stiva este o list pentru care singurele operaii permise
sunt:
-+ Stivele se pot aloca secvenial (ca vectorii). Fie ST [il un vector. ST (11,
ST (2 1, ..., ST (n) pot reine numai litere sau numai cifre. O variabil k indic
in permanen vrful stivei, adic ultimul element Introdus.
0
D Scoatem din stiv pe B (A nu poate fi scos deocamdat); k=l.
0
D Scoatem din stiv pe A; stiva rmne vid k=O.
~ Observaii
'
./ Este posibil s v ntrebai : de ce nu putem accesa un element al stivei, chiar
dac nu este ultimul introdus? Nimeni nu ne oprete~ doar c, n acest caz,
nu respectm pri'ncipiul stivei.
a
C'X: Exemple
x-1, x~12
F(x) = {
F(F(x + 2)),x < 1.2
Vom incepe prin a studia modul de calcul al funciei pentru x=lS i x=S:
f(15)=14;
f (8 )=f(f(10))=f(f(f(12))) =f(f(ll ))=f(f(f(13)))=f(f(12)) =f(11)
af(f( 1 3))=f(12)=11.
12 13
10 10 11 11
8 '1 8 8 8 8
12 13
8 11 11 12
f=11
~ Se poate demonstra uor c pentru valori mai mici decat 12, funcia ia
i -' valoarea 11. Observaia simplific mult programul, dar exemplul a fost dat n
alt scop.
l
n+1, m=0
Ack(m,n)= Ack(m-1 ,1 ), n= O
Ack(m - 1,Ack(m,n -1)),altfel
136 Capitolul 5. Structuri de date
ack(O,,ack(0,3))=ack(0,4 )5.
Pentru calculul acestei funcii, folosim o stiv dubl , ST. Iniial, valorile m i n
se rein la nivetul 1. Pe nivelul k al stivei se rein valorile curente m i n . ln funcie de
valorile acestora se procedeaz astfel:
pentru cazul n=O, se rmne pe acelai nivel in stiv, punnd in locul lui m
valoaream-1, iar n locul lui n, valoarea 1;
1 o o1
2 o 1 1 1 1 1 1
2 1 2 1 2 1 2 1 2 1
1 o
1 1 1 1
o2 1 3 1 2 1 2
g1 1 3 1 2 1 3 1 3
o1
1 1 o2
1 2 1 2 o3
1 3 1 3 1 3 o4 ack(2,1 )=5.
137
lll.anual de Informatic pent ru clasa a Xl-a
Definiia 5.4. O coad este o list pentru care toate inserrile sunt fcute
la unul din capete, toate tergerile (consultrile, modificrile) la cellalt
capt.
1 2 3 4
2 3 4 5
3 4 5 6
Probleme propuse
1. Care dintre structurile de mai jos nu este liniar?
a) b) C) d)
cemplu: k=3; V= ( 1, 2, 3); p=2. Numrul citit este 5. Dup rulare trebuie s
rem:
:4;V=(l,S,2 ,3).
cemplu: k=3; V= ( 1, 2, 3); p=2. Dup rulare trebuie s avem: k=2; V== ( 1, 3).
Pentru problema anterioar, care dintre afirmaiile de mai jos este fals?
Pentru a terge un nod aflat pe poziia p sunt necesare k-p deplasri spre
inga ale coninuturilor celorlalte noduri.
Subprogramul va avea parametrul k transmis prin valoare.
Subprogramul va avea parametrul k transmis prin referin.
Dac k=p, nu se efectueaz deplasri ctre stnga.
1
t
mului nod reine adresa primului nod, se obine o list circular:
1 ~--1--M~r 1 1 1 1 ,. . . . . . . . . . . . . ....... 1 1 1
.. 1
Creai o list circular in care fiecare nod reine un numr natural. De
: menea, scrieisubprograme de inserare i tergere a unui nod al listei create.
140 Capitolul 5. Structuri de date
10. n jurul arbitrului sunt aezai N juctori numerotai n sens orar. Arbitrul,
ncepnd de la un juctor K num r pn la M. Per.soana la care s-a oprit
num rtoarea este elimin at din cerc. Arbitrul repet procedeul ncepnd cu
persoana urmtoare celei eliminate. Procedeul se repet pn cnd rmne un
juctor L. S se scrie un program care:
Care din afirmaiile de mai jos nu este adevrat dup executarea secvenei
de mai sus?
a) Din stiv au fost extrase, in aceast ordine, valorile: 2, 4, 3;
b) stiva este vid; c) stiva conine valoarea 1; d) stiva are un singur nivel.
15. S se scrie un program care, pentru problema de mai sus, citete ca date de
intrare irul vagoanelor aflate pe linia A i irul vagoanelor care trebuie obinut pe
linia B. Se cere s se afieze irul mutrilor de tip Push nr_ vagon i Pop
nr_vagon (ai recunoscut, desigur, o structur de tip stiv) prin care se poate
obine iru l vagoanelor de pe lina B. Dac acest ir nu se poate obine, in momentul
in care se ajunge n situaia unei mutri imposibile, s se afieze mesajul
'Imposibil'.
Rspunsuri
1. d) 4. b) 11. b) 14. d)
Capitolul 6
Introducere n recursivitate
5. 1. Prezentare general
procedure exemplu(n:integer);
begin
if n<>O then
begin
writeln (n) 1
exemplu(n-1);
end
end;
begin
exemplu(?) ;
end.
function suma(n1integer)1integer;
begin
suma:=O;
if n<>O then
suma:=n+suma(n-1);
end;
begin
writeln(suma(7));
end .
i,j?~
. :~), . Funcia de mai jos este recursiv. Ea afieaz, pe rnduri separate,
~?f.' numerele 7, 6, ... , 1:
linclude <iostre am.h>
void exernplu(int n)
{ if (ni=O)
{ cout<<n<<endl;
exemplu (n- 1) ;
}
}
main()
( exernplu(7);
}
lanual de informatic pentru clasa a Xl-a 143
main()
{ cout<<suma(7);
}
A) Pentru a scrie o funcie recursiv care efectueaz acelai calcul, vom porni de
a o definiie recursiv a lui n 1. Aceasta este:
1, n= O
n! = fact(n) = { n fact(n-,) , altfel cu nE N
3 ! =fact(3)=3Xfact(2)=3X2Xfact(l)=3X2X1Xfact(0)=3X2X1Xl=6.
Funcia se autoapeleaz .
Parametrul n ia valoarea
fact=l
o. n stiv se creeaz un nou nivel, care reine n
cu valoarea o. Funcia ia valoarea 1, autoapelul
nu mai are loc. Se revine pe nivelul 3.
-+1
fact=l
Pe nivelul 3 se efectueaz calculul1*1=1.
n .-- Se revine apoi pe nivelul 2.
..J facl=6
Se revine apoi n ma in ( ) .
Il 1 3 Referin ctre p 1
p
val n prod
2 3. Referin ctre p
1 3 Referin ctre p
p
val n prod
3 3 Referin ctre p
2 3 Referin ctre p
1 3 Referin ctre p
p val n prod
Pentru c val este 3- mai mic sau egal cu 3- se efectueaz prod-Prod*val, deci p
ia valoarea 6, dup care se revine pe nivelul2, apoi 1, apoi n programul principal.
~'
.' ,1' Observaii
.. Pentru a ne familiariza cu
exemple intuitive.
raionamentul recursiv, vom porni de la cteva
~e
e
~~ Observaii
x -1 , x ;?:12
F(x) ={ F(F(x + 2)),x < 12
0 Rezolvare. Aceast aplicaie a fost tratat iterativ, prin utilizarea stivei. n cazul
tratrii recursive, nu facem altceva dect s transcriem definiia recursiv a funciei.
n+1, m=O
Ack(m,n)= Ack(m-1,1), n=O
{
Ack(m -1,Ack(m,n -1)), altfel
Varianta .~ascal
var m,n:integer; #include <iostream.h>
int m,n;
function
ack(m,n:integer) :integer; int Ack(int m,int n)
begin { if (lm) return n+1;
if m=O el se
then ack:=n+1 if (In)
el se return Ack(m-1, 1);
if n=O then ack:=ack(m-1,1) el se
el se re turn
ack:=ack(m-l,ack {m,n-1)) Ack(m-1,Ack(m,n -1));
end; }
begin main()
write('m='); readln(m); { cout<<"m"; cin>>m;
write('n='); readln(n); cout<<"n="; cin>>n;
writeln(ack(m,n) ) cout<<Ack(m,n);
end.
0 Rezolvare. Utilizm o definiie recursiv a celui mai mare divizor comun pentru
doui:l numere naturale a i b:
a a =b
cmmdc(a,b) = c~mdc(a - b, b),a > b
{
cmmdc(a,b - a),a < b
Manual de informatic pentru clasa a Xl-a 1 51
O Aplicaia 6.5. S se scrie o funcie recursiv pentru a calcula suma cifrelor unui
numr natural.
0, n=O 0, n=O
S(n) = { S(n) = {
n mod 1O+ S(n div 10), altfel n% 10+S(n 1 10), altfel
Varianta Pascal':
var n:integer 1 #include <iostream .h>
int n;
function s(n:inte ger):inte ger;
begin int s(int n)
if n=O then s:=O { if (In) return 01
e l :se s:=n mod 10 + s(n div 10) else return n%10 + s(n/10)1
endt }
begin main()
write('n ='}; readln(n }; { cout<<"n ; cin>>n1
writeln( s(n)) cout<<s (n) 1
end. }
: Varianta Pascal .
1
';
"''!''
1
.,.
!
:li:l
J 1 varianta c++ \!,,!{:t
' #include <iostream .h>
var a,b:real1 #include <math.h>
nsintege r; double a,b;
function bn(n:int eger):re al; int n;
forward;
function an(n:int eger):re alt double bn ( int n);
begin double an ( int n)
{ i f (In) return a1
if nO
then an:=a el se
el se an:=(an( n-l+bn(n -1))/3 re turn (an(n-l)+ bn(n-1)) /2;
}
end;
I.J.anual de informatic pentru clasa a Xl-a 153
main()
begin
{ cout<<"a="; cin>>a;
write('a'); readln(a);
cout<<"b=; cin>>b;
writa('b='}; readln(b};
cout<<"n="; cin>>n;
write('n='} ; readln(n);
cout<<an(n}<< ' '<<bn (n} ;
writeln(an(n ):5:10,' '
}
bn(n) : 5:10)
end.
se citete un caracter;
dac este diferit de o, se reapeleaz funcia;
se tiprete caracterul.
D Aplicaia 6.9. Se d mulimea {1,2, ... ,n} i se cer toate permutrile acesteia.
Figura 6.1.
Cazul n care nl
$ '...:
' Fie matricea de mai jos:
o 1 1 o
ooo 1
A=
o 1 1 1
1 o o o
1 1 o
1 1 1
A=
1 1 1 1
1 o o o
A=[t ~ ~ il
iar n matricea de mai jos este reprezentat un singur obiect:
A=[~ !!Il
Ca i n problemele anterioare, pentru a evita testul ieirii din matrice,
aceasta este bordat cu linii i coloane avnd valoarea "o". Algoritmul este tot cel
din problema anterioar (FIII), dar aici cutarea se face pe 8 direcii.
n programul principal se citete matricea i se caut primul element "1"
printre elementele acesteia. Se apeleaz apoi funcia compact< > care are rolul de
a marca cu o toate elementele matricei care aparin acestui prim obiect identificat.
La revenire, se testeaz dac mai exist elemente cu valoarea "1" n matrice. n
caz afirmativ, se poate trage concluzia c n fotografie aveam Iniial mal multe
obiecte (altfel, fotografia coninea un singur obiect) .
, '''ii'
,,JI, ' '
,". . :yarl~nta Pascal
j
Z~egin main()
~ite('M='}; readln(m); { cout<<"M=";cin>>m;
~ite('N='}; readln(n); cout<<"N=";cin>>n;
for i:=l to m do for (i=l;i<=m;i++)
for j:=l ton do for (j=l;j< .. n;:i++)
begin { cout<<"a["<<i<<','
wri te ( 'a [ ' 1 i 1 ' , ' 1 j, ' ] =' ) ; <<:i<<"l=";
readln(a[ilj]) cina[i] [j];
end; }
for i:=l to n do for (i=l;i<=n;i++)
begin { a(O] [i]=O;
a(O,i]:=O; a(m+ll [i]=O;
a(m+l,il :=O; }
end; for (i=l ; i<w.m;i++)
for i:=l to m do { a[i] [0]=0;
begin a[i] (n+ll=O;
a(i,O]:=O; }
a(i,n+l] :0 x=O ;
end; do
x:sO; { X++;
repeat y=O;
x:=x+l; do
y:=O; { y++;
repeat while (y 1=n &:&: a [x] [y] 1=1) ;
y:=y+l }
until (y=n) or (a[x,y]=l) while ((xl.,m) &:&:a[x][y]l=l);
until (x=m) or (a[x,y]l); compact(x,y,a);
compact(x,y,a); gasit=01
gasit:=false; for (i=l;i<=m;i++)
for i:=l tom do for (j=l;:i<=n;:i++)
for j :=l ton do if (a[i] [j]==l) gasit=l;
if a[i,j]=l then if (ga sit)
gasit: .. true; cout<<"mai multe obiecte" ;
if gasit else cout<<"un obiect";
then wri teln ( mai mul t .e }
obiecte)
else writeln( un obiect')
end .
Probleme propuse
a) 1X2+2X3+ +nx(n+1);
b) 1+1/2+ +1/n;
c) 1/(2X3)+2/(3*4)+ +n/((n+l)(n+2)).
160 Capitolul 6. Introducere n recursivitatE
7. Scriei un subprogram recursiv care cal culeaz cte cuvinte distincte cu 2r.
caractere se pot forma cu n caractere A i n caractere B.
V(J], Il = 1;
max(V[l],V[2], ... V[n]) =
{ max(max(VP ], V[2l, ... vrn - 1]), Y[nl) altfel.
10. Scriei o funcie recursiv care testeaz dac un numr natural n>l este prirr
11. Scriei o funcie recursiv care returneaz suma elementelor pare ale ur-
vector citit.
Exemplu: Pentru n4 i V= ( 2 1 2 1 s 1 6) , se returneaz 1 o.
12. Scriei o funcie recursiv prin care se testeaz dac un numr natural x s:c
regsete ntre componentele unui vector v cu n numere naturale.
13. Scriei o funcie recu rsiv care primete ca parametri dou numere natura:
i<j i un numr real xe [ i1jl i returneaz [xJ (parte ntreag din x). Nu s;
vor folosi funciile specializate ale limbajului.
::e informatic ntru clasa a Xl-a 161
:..: 1eio funcie recursiv care returneaz numrul cifrelor pe care le are un
..:. 'latural primit ca parametru.
O, k>n
S(n,k)== 1, kE {l,n}
{S(n -1 , k - 1) + kS(n - 1, k) 1< k< n
26. Calculai iterativ i recursiv cel mai mare divizor comun pentru dou numere
naturale m i n, utiliznd algoritmul lui Euclid:
a) 12;
b) 21;
c) eroare de executare;
d) o.
28. Ce calculeaz funcia urmtoare?
Varianta Pasc~l
fl,lnction
begin
if n<>O then return (n%2=0)*n +t(n-1);
t:ord(n mod 2=0)*n+t(n-1) elae return O;
else t: O; }
end;
~ Pentru care dintre numerele de mai jos, care sunt parametri de intrare pentru
:cia urmtoare, ultimele 2 numere afiate vor fi o?
~} 295;
~) 1024;
:. ) 1000;
:. ) 10000.
i v2 .. (4,5,1) ce se afieaz la
30. Dac n este egal cu 3, Vl:o(l, 2,3)
apelul t (n, 1, 1)?
a) 1 2 3;
b) 1 4 2 5 3 1;
c) cerina nu este corect;
d) 4 5 1.
164 Capitolul 6. Introducer e n recursivitate
31. Care dintre afirmaiile de mai jos sunt corecte dac n este 3 i apelul este
t(n,1,1) ?
a)
ntotdeauna se vor afia cel mult 6 numere;
b) ntotdeauna se vor afia cel puin 3 numere;
c) ntotdeauna se vor afi a cel mult 3 numere;
d) ntotdeauna se vor afia cel puin 6 numere.
32. Dac n este 3, pentru care din datele de mai jos se afieaz un numr maxirr
de valori distincte, dac apelul este t ( n, 1, 1)?
a) 1 2 3; b) 1 2 3 4 5 6;
c) 4 5 6; d) nici o valoare.
. Dac n=4, pentru care dintre valorile de mai jos ale lui m se afieaz dou
ori?
b) 3; c) 2; d) 1.
37. n funcia de mai jos nlocuii linia cu una dintre instruciunile urmtoare,
11
11
astfel nct funcia s-i ncheie execuia fr eroare pentru orice valoare admisibil
a argumentului:
Varianta Pascal
x(n:inte ger):inte gerl int x(int n)
begin {
if n<>O then if (n)
begin (
writeln( n); cout<<n1
end }
end; }
38. Dac funcia este apelat prin an< 4), de cte ori se autoapeleaz?
39. Pentru care dintre valorile de rnai jos, care sunt parametri de intrare pentru
funcia an, executarea funciei se termin cu eroare?
40. Pentru programul de mai jos, de cte ori se autoapeleaz funcia an?
..
'!<
;pf Varianta
. .r.
~
Pascal
. . . ~1; 1 :
- o
' - ti
" ~<' .
~: ,:. ;.1~"'
h ~~. ' ~' .~:~,,,; V~rianta:.~t:+ ~!:: ,,,!;~ .,..
functio n an(n:in teger):i nteger; #includ e <iostrea m.h>
begin int an( int n)
i f n=O then an:=2 { if (n==O) re turn 2;
el se el se
if n=l then an:=-1 if (n1) re turn 1;
el se an:=an( n-1)-an (n-2)+1 el se
end; re turn an(n-1) -an(n-2 )+1;
}
begin
writeln (an(4)) ; main()
end. { cout<<a n(4); }
Indicaii / Rezolvri
Sn = {0, dacan = O
Sn_1 +n, altfel
(2n) =C"
n:n.
' ' 211
8.
,,. .
ifil~:' ::~~~
.... ,::~.
1 1 -::-
Varianta Pascal V~r,lanta C++ ' -, c ;
' ' ',
1 then Prim:=fals e
else Prim:Prim (n,i+l);
end;
1
11.
12.
function
Palindrom(i,j:integer):boolean;
begin (i>=:ll roturn 1;
if i>=j eloo
then Palindrom:=true if (V[i] I=V[j]) return O;
el se else return
if V[i] <>V[j] Palindrom(i+1,j-1);
then Palindrom:=false }
else Palindrom:=
Palindrom(i+1,j-1);
end;
15.
1 ~ 1
Varianta Pascal ,
'.
, ''' ' .. ,. Varlanta C++ il
funotio n int Distinc te(int i,int n)
Distinc te(i,nzi nteger) zboolea n; { int gasit,j ;
var gasit:bo olean; if (i=n) return 1;
j:integ er; el se
begin { gasit=O ;
if i=n for (ji+1;j <=nJj++ )
then Distinc teztrue if (V[il ==V[j)) gasit=l ;
el se if (gasit) return O;
begin e lse return
gasitz false; Distinc te(i+1, n);
for jzi+1 ton do )
i f V[i] =V[j] }
then gasit:= true;
if gasit
then Distinc te:=fals e
else Distinc te:=
Distinc te(i+1,n );
end
end;
170 ' Capitolul 6. Introducere n recursivita te:
27. a); 28. d); 29. b); 30. a); 31. a), b); 32. a); 33. d);
38. a) ; 39. b) ;
40. a) Autoapelurile se efectueaz dup schema de mai jos:
Acum, vedei "pe viu" motivul pentru care, n cazul unor astfel de formule de
recuren, n care, n expresie, intervin mal muli operanzi ce se calculeaz
.
recursiv, este de preferat metoda iterativ.
Capitolul 7
Metoda DIVIDE ET IMPERA
7.2. Aplicaii
:;' Rezolvare. Trebuie tiprit valoarea maxim dintre numerele reinute n vector de
~:.. la j (iniial i=l i j =n).
---
---
-----~
1.4anual de informatic pentru clasa a Xl-a 175
-
- . ~~~~~~
176 Capitolul 7. Metoda D IVIDE fT IMPERJ.
Avem:
T(n) = T(2k) = 2(T(2k-l) + 2k-l ) = 2T(2k-l) + 2k =2T(2k- 2 + 2k-l ) + 2k =
2
2T(2k- )+2k +2k =...2k +2k + ... +2k =n+n+ ... +n =n k =n log 2n
'------v--'
dekori de kori
O Problema 7.3. Fie vectorul a cun componente numere ntregi (sau reale). Se
cere ca vectorul s fie sortat cresctor.
0 Rezolvare. Este necesar o funcie POZ care trateaz o poriune din vector
cuprins ntre indicii dai de l i (limita inferioar) i ls (limita superioar) . Rolt.
acestei funcii este de a poziiona prima component a [li] pe o poziie k cuprins.1
ntre l i i ls, astfel nct toate componentele vectorului cuprinse ntre l i i k-l
s fie mai mici sau egale dect a [kl i toate componentele vectorului cuprinse
ntre k+1 i ls s fie mai mari sau egale d~ct a [k).
i=l, j=S;
a[1 J >a [S], deci se inverseaz elementele aflate pe poziiile 1 i 5,
deci a= ( 2, 9, 3, 1, 6) i programul trece la modul de lucru b) ;
i =2 , j=5;
a [21 >a [51, deci a= (2,6 ,3, 1,9) i se revine la modul de lucru a);
i=2, j=4;
a [ 2 1 >a ( 4], deci a= ( 2, 1, 3, 6, 9); se trece la modul de lucru b );
ic:3, j=4;
funcia se ncheie, elementul aflat iniial pe poziia 1 se gsete
acum pe poziia 4, toate elementele din stnga lui fiind mai mici
dect el, totodat toate elementele din dreapta lui fiind mai mari
dect el (k=4).
f Dup aplicarea funciei POZ, este evident c elementul care se afl iniial n
poziia l i va ajunge pe o poziie k i va rmne pe acea poziie n cadru l
vectorului deja sortat, fapt care reprezint esena algoritmului.
se apeleaz Poz ;
se apeleaz QUICK pentru l i i k-1 ;
se ape l eaz QUICK pentru k+l i ls.
l'
Varianta Pascal
type vector=array [1 .. 100] of #include <iostream.h>
integer; int a[100],n,k;
void poz (int li,int ls,int&
var i,n,k:into ger;
k,int a[100])
a :veotor;
{ int i=li,:l=ls,c,i1=0,~1=-1;
procedura poz (li,ls:integer; while (i<:l)
var k:integ er; { if (a[i]>a(j])
va.r a:vector); { c=a (j]; a[j]=a[i];
a[il=c; c=il;
var i,j,c,i1,j1:integ er; i1=-:11; :11=-c;
begin }
i=i+il;
i1:=0; :1=:1+:11;
jl:=-1; }
i:=li; k=i;
j:=ls; }
178 Capitolul 7. Metoda DIVIDE ET IMPERA
while i<j do
void quick (int li,int ls)
begin { if (li<ls)
i f a[i] >a[j]
{ poz(li,ls,k,a);
then
quick(li,k-1);
begin
quick(k+l,ls);
c:=a[j]; }
a [ j] : a [ i] ; }
a [il :=c;
CJil; main()
il:=-jl; { int i;
jlJ-c cout<<"n="; ein>>n;
end~
for (il;i<n;i++)
i:=i+il;
{ eout<<"a["<<i<<"l";
j:j+jl
cina[i];
end; }
k:=i
quick(l,n);
end;
for (il;i<n;i++)
procedura quick(li,ls:integer); cout<<a[i)<<endl;
begin }
if li<ls
then
begin
poz(li,ls,k,a);
quick(li,k-1);
quick(k+l,ls)
end
end;
bagin
write( 'n');
readln(n) 1
for i:l to n do
bagin
write(a[,i,]');
readln(a[i])
end;
quick(l,n); ..,.
for i:l to n do
writeln(a[i])
end.
~ Rezolvare.
Dac n=1, se face mutarea ab, adic se mut discul de pe tija a pe tija b.
ab, n= 1
H(n,a,b,c) ={ H(n - 1,a,c,b),ab,H(n - 1, c, b, a), n >1
h 1 xv(i),yv(i)
x,y
Pentru a se afla n interiorul dreptunghiului, gaura trebuie s ndeplineasc
simultan cond ii ile:
1) xv(i) >x;
2) xv(i) <x+l;
3) yv(i) >y;
4) yv(i)<y+h.
Dac facem o tietur vertical prin aceast gaur, obinem dou dreptunghiuri:
1) x, y, xv(i) -x, h;
2) xv(i), y, l+x-xv(i), h.
1) X, y , l , yv ( i) -y;
2) x, yv(i), 1, h+y-yv(i ).
if. gasit el se
then if (l*h>lf*hf)
begin { xf=x;
dimp(x,y,xv[i]-x , yf..y;
h,xf,yf,lf,hf,xv, yv)l lfl;
dimp(XY[i],y,l+x -xv[i], hfh;
h,xf.,yf,lf,hf.,xv ,yv); }
dimp(x,y,l,yv[i] -y, }
xf.,yf,lf,hf,xv,y v)l
dimp(x,yv[i],l,h +y-yv[i], main ()
xf.,yf,lf,hf,xv,yv ) { cout<<"n"1 cin>>n1
end for (int il;i<n1i++)
el se { cout<<"x["<<i<<" ]c;
i f (l*h)>(lf*ht) cinxv[i];
then cout<<"Y["<<i<<" l"1
begin cinyv [il 1
XfiXI )
yfiYI oout<<"1"1 cin>>l1
lf.al1 cout<<"h"; cin>>h1
hflh dimp(O,O,l,h,xf ,yf,lf,
end hf,xv,yv);
cout<<"x"<<xf<< " y"<<yf
<<" l"<<lf<<" h "<<hf1
begin )
write ( 'n') ;
readln(n);
for ial to n do
begin
write ( 'x [ , i, l ) 1
readln(xv[i]);
~1ri te ( y [ ' , i, l ) 1
readln(yv[i])
end;
write( '1');
readln(l)l
write( 'h ) 1
readln(h) 1
lf :O;
h.f :01
dimp(O,O,l,h,xf, yf,
lf,hf,xv,yv) 1
writeln( 'x' ,xf, Y' ,yf.,
1' ,lf,. h',hf)
end.
Manual de informatic pentru clasa a Xl-a 183
7.3. Fractali
initgraph(gdriver,gmode,'cale');.
2) prin indicarea cu ajutorul primilor doi parametri a unui driver i a unui mod
de lucru solicitate de programator (n acest caz, nu se poate executa programul pe
un calculator ce nu este dotat cu placa grafic specificat):
gdriver := VGA;
gmode :"' VGAHI;
initgraph(gdriver,gmode,'cs\tp\bgi');
if graphresult<>O then
begin
writeln("Tentativa esuata!");
halt
end;
Tentativa de iniializare grafic poate eua din diverse motive, cum ar fi: lipsa
unitii
GRAPH, calea indicat greit, etc. Testarea se realizeaz cu funcia tntreag
graphresult care returneaz o n caz afirmativ i o valoare diferit de o, n
caz contrar.
initgraph(&gdriver,&gm ode,"oale"); .
2) prin indicarea cu ajutorul primilor doi parametri a unui driver i a unui mod
de lucru solicitate de programator (n acest caz, nu se poate executa programul pe
un calculator ce nu este dotat cu placa grafic specificat):
Tentativa de iniializare grafic poate eua din diverse motive, cum ar fi: lipsa
un itii GRAPHICS , ca lea i ndicat greit, etc. Testarea se realizeaz cu funcia
,
ntreag graphre sul t ( ) care returneaz o n caz afirmativ i o valoare diferit
de o, n caz contrar.
Ateniei Pentru a putea scrie i rula programe C++ ce utilizeaz modul grafic al
limbajului, trebuie bifat urmtoarea opiune , din meniu:
f Aceste culori sunt cele implicite. Pentru a utiliza mai multe culori (dar nu n
J,jitl acelai timp), se poate schimba setul (paleta) de culori. ntruct n acest
moment nu sunt necesare o multitudine de culori, nu vom prezenta n detaliu
acest aspect.
..,a., ual de Informatic pentru clasa a Xl-a 187
setbkcolor(c uloare);.
~ Observaii
Operaia de desenare
VarlantaP~scal
begin main ()
initg; { init() 1
setcolor(red ); tcolor(RED ) 1
moveto(O,O); moveto(O,O);
lineto(getmax x,getmaxy); lineto(getma xx(),getmaxy ());
readln1 getch() 1
end. }
_/\_
Figura 7.1. Exemplu de transformare
Fiecare latur a acestui poligon se transform din nou, dup aceeai regul.
S se vizualizeze figura obinut dup ls pai {n um r citit de la tastatur).
Y1 - k Y2
1-k
Demonstrai singuri aceste formule!
k = DA =-2
DB '
x = x 1 +2x 2
1' 3 ' Y,, = Y1 +2
3 -
)'?
begin if (n<ls)
rotplan((2*xl+x2) div 3, {generator(x1,y1,div((2*xl+x2),
(2*yl+y2) div 3, (x1+2*x2) div 3).quot,div{(2*yl+y2),
3, (y1+2*y2) div 3,x,y,pi/3); 3).quot,n+l,ls);
if n<ls then generator(div((2*xl+x2),
begin 3).quot,div((2*yl+y2),
generator(xl,yl, (2*xl+x2) 3),quot,x,y,n+l,ls);
div 3,(2*y1+y2) div 3, generator(x,y,div((x1+2*x2),
n+l, ls); 3).quot,div((y1+2*y2),
generator{{2*xl+x2) div 3, 3).quot,n+l,ls);
(2*yl+y2) div 3, generator(div((x1+2*x2),
x,y,n+l,ls); 3).quot,div((y1+2*y2),
generator(x,y, (x1+2*x2) div 3).quot,x2,y2,n+l,ls);
3,(y1+2*y2) div 3,n+l,ls); }
generator({x1+2*x2) div 3, else desenez(xl,yl,x2,y2,x,y);
(yl+2*y2) div 3, }
x2, y2, n+l, ls);
main()
end
{ cout<<"ls= "; cin>>ls;
else desenez{xl,yl,x2,y2,x,y);
init ();
end;
setcolor(6);
begin L = getmaxx()-320;
write('ls= '); readln(ls); generator(160,getmaxy()-150,
initg; 160+L,getmaxy()-150, 1,ls) ;
setcolor(red); generator(160+L,getmaxy()-
L:=getmaxx-320; 150,160+div(L,2).quot,
generator(l60,getmaxy-150, getmaxy() -150-
160+L,getmaxy-1SO,l,ls)/ ceil(L*(sqrt(3)/2)),l,ls);
generator(160+L,getrnaxy-150, generator(160+div(L,2) ,quot,
160+L div 2,getmaxy-150 - getrnaxy() -1SO-
L*round(sqrt (3)/2) , 1,ls) ; ceil(L*{sqrt(3)/2)),160,
generator(160+L div 2,getmaxy- getmaxy()-lSO,l,ls);
150-L*round(sqrt(3)/2),160, setfillstyle(1,4);
getmaxy- lSO,l , ls)/ floodfill(div(getmaxx(),2)
setfillstyle(l,blue); .quot,div(getmaxx(),
floodfill(getmaxx div 2, 2).quot,6);
getmaxy div 2, red); getoh()/
readln closegraph();
end . }
Privii mai jos rezultatele obinute pentru diferite valori ale lui la:
la = 2 ls ::: 3 ls =4
Figura 7.2. Exemple de fractali formai cu ajutorul curbei lui Koch (triunghi echilateral)
"'.anual de informatic pentru clasa a Xl-a 191
Fiecare segment al liniei frnte astfel formate se transform din nou dup
aceeai regul. Se cere s se vizualizeze curba dup ls transformri (valoare
citit de la tastatur).
procedura desen(xl,yl,x 2,
y2,n,ls:inte ger); void rotplan(int xc,int yc,
var x3,x4,x5,x6, x7,x8,xc, int xl,int yl,int &x,int &y,
y3,y4,y5,y6, y7,y8,yc:inte ger; float unghi)
{
begin
}
if n<=ls then
begin void desen(int xl,int yl,int
x3:=(3*xl+x2 ) div 4; x2,int y2,int n,int ls)
y3:=(3*yl+y2 ) div 4; { int x3,x4,x5,x6, x7,x8,
rotplan(x3,y 3,xl,yl,x4,y4 , xc,y3, y4,y5,y6,y7, y8,yc;
-pi/2); if (n<=ls)
xc:=(xl+x2) div 2; { x3=div(3*xl+ x2,4) .quot;
yo:=(yl+y2) div 2; y3=div(3*yl+ y2, 4).quot;
rotplan(xc,yo ,x3,y3,x5,y5 , rotplan(x3,y 3,xl,yl,x4,y4 ,
-pi/2); -M_PX/2);
rotplan(xc,y c,x3,y3, xc=div(xl+x2 ,2) .quot;
yc=div(yl+y2 ,2).quot;
x6,y6,pi/2);
rotplan(xc,y c,x3,y3,x5,y 5,
x8:=(x1+3*x2 ) div 4;
-M_PI/2);
y8:=(y1+3*y2 ) div 4;
rotplan(xc,y c,x3,y3,x6,y 6,
rotplan(x8,y 8,xc,yc,x7,y 7,
M_PJ:/2);
pi/2); x8=div(x1+3* x2, 4).quot;
desen(xl,yl, x3,y3,n+l,ls ); y8=div(yl+3* y2, 4) . q uot;
desen(x3,y3 ,x4,y4,n+l,ls ); rotplan(x8,y 8,xc,yc,x7,y 7,
desen(x4,y4, x5,y5,n+l,ls) ; M_ PJ:/2);
desen(xS,yS ,xc,yc,n+l,ls ); desen(xl,yl, x3,y3,n+l,ls );
desen(xc,yc, x6,y6,n+l,ls) ; desen(x3,y3 ,x4,y4,n+l,ls );
desen(x6,y6, x7,y7,n+l,ls) ; desen(x4,y4, x5,y5,n+l,ls) ;
desen(x7,y7 ,x8,y8,n+l,ls ); d e sen(xS,yS , xc,yc,n+l,ls );
desen(x8,y8 ,x2,y2,n+l,ls ); desen(xc,yc, x6,y6,n+l,ls );
if n = ls then begin desen(x6,y6 ,x7,y7,n+l,ls );
moveto(xl,yl ); desen(x7,y7 ,x8,y8,n+l,ls );
lineto(x3,y3 ); desen(x8,y8, x2,y2,n+l,ls) ;
lineto(x4,y4 ); if (n == ls)
lineto(xS,yS ); { moveto(xl,yl );
lineto(x6,y6 ); lineto (x3 , y3) ;
lineto(x7,y7 ); lineto(x4 , y4);
lineto(x8,y8 ); lineto(xS,yS );
lineto(x2,y2 ); lineto(x6,y6 );
lineto(x7,y7 );
end
lineto(x8,y8 );
end
lineto(x2,y2 ); }
end;
}
begin }
write('ls= '); readln(ls); main()
initg; setcolor(red ); ( cout<<"ls= "; oin>>ls;
desen(100,10 0,300,100,1, ls); init(); setcolor{6);
desen(300,10 0,300,300,1,1 s); desen(100,10 0,300,100,1, ls);
desen(300,30 0,100,300,1, ls); desen(300,10 0,300,300,1, ls);
desen(100,30 0,100,100,1,1 s); desen(300,30 0,100,300,1, ls);
setfillstyle( l,blue); desen(100,30 0,100,100,1, ls);
floodfill(getm axx div 2, setfillstyle( 1,3);
getmaxy div 2, red); floodfill(div {getmaxx(),2 )
readln .quot,div(ge tmaxy(),2).q uot,6);
end. getch(); closegraph() ;
.anual de informatic pentru clasa a Xl- a 193
Sunt prezentate mai jos imaginile obinute n urma rularii programului, pentru
4
:: erite valori ale lui ls:
ls==l ls=2
Figura 7.4. Exemple de fractali formai cu ajutorul curbei lui Koch (ptrat)
7.3.4. Arborele
Pentru diverse valori ale parametrului de intrare ls, vom obine arborii:
ls =3 ls =5 ls =7
Figura 7.6. Exemple de fractali de tip arbore
~ Observaii
~ Exemplele grafice prezentate au fost generate pentru valori mici ale lui ls
deoarece la tiprire, detaliile sunt greu de observat peste o anumit limit .
Probleme propuse
1. Se citete a~1. numr real. Se cere s se scrie o funcie care calculeaz ln(a)
cu 3 zecimale exacte. Nu este permis utilizarea funciei logaritmice a limbajului.
2. Scriei o funcie care calculeaz prin metoda DIVIDE ET IMPERA suma numerelor
reinute dintr-un vector.
5. Se tie c ecuaia x 3 +x-1=0 are o singur rdcin real Tn intervalul <o, 1).
Scriei un program, care o afieaz cu 4 zecimale exacte.
196 Capitolul 7. Metoda DIVIDE ET IMPERA
Rspunsuri
1. ln (a) =x (::> a=e>C (::> ex-a=O. Dac notm cu f (X) =ex-a, atunci trebuie
rezo lvat ecuaia f(x)O. Avem f(O)=e 0 -a==1-a<O i f(a)=e 4 -a>O. De
aici,
rezult c f(x) are o rdcin n intervalul (O,a). Cum f(x) este
strict
cresctoa re (ca diferen ntre funcia strict cresctoare e" i o constant ),
rdcina este unic . Algoritmul pe care l folosim se numete n matematic
"metoda Tnjum~t~irii intervalului', dar, din punct de vedere informatic, corespund e
metodei DIVIDE ET IMPERA.
Fie liaO i lsa, m=(a+b) /2. Dac f(li)Xf(m )<O, rdcina se gsete n
(li,m) , altfel rdcina este n [m,ls) . Condiia de terminare este ca
jli - lsj < 0.0001, pentru c trebuie s avem 3 zecimale exacte.
begin main()
write {'a=' ) ; readln(a); { cout<<"a="; cin>>a;
writeln(' rezultat cout<<"rezultat calculat "
calculat:',LogN(a,O,a):3 :3); <<LogN(a,O,a)<<endl;
writeln(' rezultat preluat cout<<"rezultat preluat "
ln(a):3:3); <<log(a)<<endl;
end. }
5. Vedei problema 1.
6. Funcia Poz returneaz pozii a k pe care se va gsi, dup rularea ei, primul
element al vectorului. n plus, toate elementele de indice mai mic dect k sunt mai
mici sau egale dect A [kl i toate elementele de indice mai mare dect k sunt mai
mari sau egale dect A [kl . Altfel spus: elementul A [ 11 , care se afl dup rularea
funciei pe poziia k, este al k-lea cel mai mic element din vectorul A. Atunci, n
cazul n care k=t , problema este rezolvata. Dac t<k, elementul cutat are
indicele cuprins ntre l i i k-1 i relum rularea funciei Poz ntre aceste limite, iar
dac t>k, elementul cutat are indicele ntre k+l i ls i rel um rularea fu nciei
Poz ntre aceste limite. Datorit faptului c, la fiecare pas, se restrnge numrul
valorilor de cutare, se ajunge n situaia n care t=k.
Secvena este:
lil=1; li=l;
ls:=n; ls=n;
repeat do
poz(li,ls,k,a); { poz(li,ls,k,a);
if t<k then lsJ=k-1; i f (t<k) ls=k-1;
if t>k then li:=k+l; i f (t>k) lia k+1;
until t=k; }while ( t 1=k) ;
writeln('Elementul cautat cout<<"elementul cautat "
a [t]) 1 a[t] 1
soluia lor poate fi pus sub forma unui vector S=xl,x::~, .. ,x0 , cu
X1EA1 , X 2 EA::~, . .. , XnEAo;
{1,2,3}X(1,2 ,3}X{1,2,3} :{11, 12, 13, 21, 22, 23, 31, 32, 33}
X{1,2,3)= {111, 112, 113, 121, 122, 123, 131, 132, 133, 211,
2 12, 213, 221, 222, 223, 231, 232, 233, 311, 312, 313, 321,
322, 323, 331, 332, 333}.
200 Capitolul 8. Metoda backtracking
Principiut metodei
j,f, 1 1
rl::,,. ' Varianta C++ ...r,,,,. "'..":; .
,"'" v~~la"'ta ~~scai .. l",. : !:r 1 '/: lr, .
Pentru permutri, vom avea o soluie cnd s-a generat o secven alctuit din n
numere distincte. Cum subprogramul este recursiv, acest fapt se intmpl atunc1
cnd s-a ajuns pe nivelul n+l.
De exemplu, dac n=4, o soluie este reprezentat n figura 8.1., a). Modul de
obinere al soluie i este prezentat n figurile urm toare, de la b) la i):
~ .:
\lW 1 "
~
' '
,.... " .. ' ' !1: i.:,"
l .r. ,,, ...
" li '
a) b) c)
.-!.;:,~.
~
~-\
~
1'11 1'
1 ~ ~
:
',. ~ ...
~ 'i:::;jl:,
!" :r;;-!:- .11:
1;: ti,..: '
1 '
d) e) f)
,..,
~ ~
li:;. :;ii'' ' ;1 1!
-
1. :.:'
1
\liV \lW
~ \}JV
'::' ~
g) h) i)
lsol(i) -sol(j)l=li-jl
(diferena, n modul, dintre linii i coloane este aceeai).
Exemple:
a)
sol(l) = 1 i 1
sol(3) = 3 j = 3
lsol(l) - sol(3) 1 = 11 - 31 a 2
l i - jl = 11 - 31 = 2
Agura 8.2.
206 Capitolul 8. Metoda backtracking
b)
sol(l) = 3 i 1 =
sol(3) = 1 j =3
lsol(i) - sol(j) 1 = 13 - 11 = 2
li- jl = 11- 31 = 2
Figura 8.3.
Exerciii
? Este Tntotdeauna necesar s-I folosim pe acesta sau putem reine numai
ideea i, dup caz, s scriem mai puin?
! .,. (, ,..,,..
Varianta Pascal .;, : ..'' Varianta C++
var sol:array[1 9] of integer; #include <iostream.h>
n:integer1 #include <math.h>
int n, sol[lO];
function
valid(k:integer):boolean l int :valid(int k)
{ for (int i=l;i<k;i++)
var i :integer; if {sol [k] ==sol [il 11
begin abs(sol[k]-sol[i])
valid:true; ==abs(k-i))
for i:=l to k-1 do return O;
if (sol[k]=sol[i]) or return 1;
(abs(sol(k]-sol[i])=abs( k-i)) }
then void back ( int k)
valid:=false { if (k==n+l) // solutie
end; //tipar
{ for (int i=l;i<=n;i++)
procedura back(k:integer); cout<<sol[i];
cout<<endl;
var i:.integer; }
begin el se
if kn+l {solutie} { sol[k]cO;
then while(sol[k]<n)
begin 11 succesor
{tipar} { sol[k]++i
for i:=l to n do if (valid(k))back(k+l);
write(sol[i));
writeln; }
end
main()
el se
begin { cout<<"n'""l cin>>n;
sol[k] :=O; {init} back(l);
while sol[k]<n do }
{succesor}
begin
sol[k]: .. sol[k]+l;
if valid(k)
then
back(k+l)
end
end
end1
begin
write( 'n=');
readln(n);
back(l)
end.
~ Exerciii
1. Testai subprogramuf anterior pentru problema generrii permutrilor.
~ Este demonstrat faptul c sunt suficiente numai 4 culori pentru ca orice hart
.~ s poat fi colorat.
Pentru exemplificare, vom considera harta din figura 8.4., unde rile sunt
numerotate cu cifre cuprinse ntre 1 i 5 .
ara 1 - culoarea 1;
ara 2 -culoarea 2;
ara 3 -culoarea 1;
ara 4 -culoarea 3;
Figura 8.4.
ara 5 - culoarea 4 .
Manual de info rmati c pentru clasa a Xl-a 211
Exerciii
E,x: Exemple
O Enun. Se dau n mulimi: A1, A 2 , ... A", unde A1 =U1 2 1 ... 1 k 1 }, pentru
k==1, 2, 1 n. Se cere produsul cartezian al celor n mu limi.
J~ Observaii
1. Avem k1Xk:.~x... xk,. elemente ale produsului cartezian. De aici rezult c
algoritmul este exponenial.
A... produsul cartezian al lor A1XA:.~x XAz. se mai numete spaiul soluiilor. n
acest context, metoda backtracking caut una sau toate soluiile, care sunt
elemente ale produsului cartezian i care indeplinesc anumite condiii. Astfel, se
poate justifica faptul c, n generarea produsului cartezian, nu este necesar
subprogramul valid pentru c se genereaz toate elementele produsului
cartezian, fr a verifica anumite condiii.
Manual de informatic pentru clasa a Xl-a 2 ,-
.~
~ Exerciii
1. Tabelarea anumitor funcii. Se d funcia
unde fiecare mulime A1 este dat de numerele ntregi din intervalul [a 1 ,bd i
2. Scriei programul care genereaz toate "cuvintele" cu patru litere care au pdma
i ultima liter vocale, litera a doua consoan din mulimea {P, R, s, T} , iar a treia
1ter consoan din mulimea {B, M, R, T, V}.
3. Scriei programul care genereaz i numr eate cuvinte de cinci litere ale
alfabetului englez se pot forma, cu condiia s nu existe dou consoane al turate
i nici dou vocale alturate .
::J Enun. Fiind dat mulimea A={1 1 2, ,n}, se cere s se afieze toate
SJbm ulimile ei.
~ Exerciii
valor.:
1. Problema nu este rezolvat in totalitate. Programul afieaz numai toate
program ul s.:
pe care le poate lua vectorul caracteristic. Completai-! astfel incat
afieze oate submulimile mulimii <1, 2 n} 1
in baza ;.
3. S se afieze toate numerele scrise in baza 10 a cror reprezentare
cu 1. Valorile n i k se citesc de ..i
are n cifre, dintre care exact k sunt egale
tastatur (n<12, k<n). De exemplu, pentru n:c3 i k2, se obin valorile: s i 6.
,
1
Observaii
Fiind dat o mulime
cu n elemente, avem 2n submulimi ale ei. Mulimea
dat~ i submulimea vid sunt submulimi ale mulimii datei De ce? Fiecare
component a vectorului caracteristic poate reine dou valori. Prin urmare,
numrul de submulimi este
222
~
...2=2" .
uenori
CP = n!
n (n - p)!p!
~---- -r~=~- -
218 Capitolul 8. Metoda backtracking
sol[n-1]<sol(n]~-p+p=n.
Relaiile de mai sus simplific mult algoritmul, pentru c innd cont de ele, nu mai
este necesar s se testeze nici o condiie de continuare.
.".fi Exerciii
Se dau coordonatele din plan a n puncte. Afiai coordonatele vrfurilor tuturor
::c:ratelor care au ca vrfuri puncte din mulimea considerat.
: xemplu: p=2, n=3. Avem: 12, 21, 13, 31, 23, 32. De exemplu, 21 este funcia
: :A-4B dat astfel: f (1) =2; f (2) =1. Avem relaiile:
ni
A~ = = n(n-1) ... (n-p+1).
(n - p)!
Pe de alt parte, se poate lucra mult mai eficient. O soluie este de forma:
x1x2 xp. unde x1, x:~, ... , XpEB. n plus, x 1, x:~, ... , Xp trebuie s fie distincte.
Spre deosebire de algoritmul de generare a combinrilor, aici ne intereseaz toate
permutrile unei soluii (acestea sunt, la rndullor, alte soluii). Aceasta nseamn
c nu mai putem pune n soluie elementele n ordine cresctoare. S recapitulm:
._ d
Varianta C++
~ Exerciii
care se pot forma
1. Se citesc n, p i apoi n litere distincte. Afiai toate cuvintele
cu p dintre ele.
numele care se
2. Se citesc n i apoi: numele mici a n persoane. tiind c toate
nume de biei, s se afieze
termin cu a reprezint nume de fat, celelalte fiind
Dou mulimi sunt distincte
toate mulimile de perechi fat-biat care se pot forma.
lu, pentru n=S, Maria , Ana,
dac cel puin una dintre perechi difer. De exemp
a-Dor u, Ana-C osmin },
Doina , Doru, Cosmi n, se afieaz mulimile: {Mari
{Doin a-Dor u,
{Ana- Cosmi n,Mar ia-Dor u}, {Mari a-Dor u,Doin a-Cos rnin},
-Cosm in}.
Maria -Cosm in}, {Ana- Doru,D oina-C osmin }, {Doin a-Dor u,Ana
Manual de informatic pentru clasa a Xl-a 221
0 Rezolvare. Chiar dac tim s generm toate submulimile unei mulimi, tot nu ne
ajut s generm toate partiiile.
1 Pentru a putea genera toate partiiile, trebuie s gsim o metod prin care s
putem reine o partiie. O prim idee ne conduce la folosirea unui vector, sol, astfel:
dac sol [il k, atunci elementul i se gsete n mulimea k a partiiei. Totui, nu
tim cte mulimi sunt in partiia respectiv . Exist o partiie care conine n mulimi
atunci cnd fiecare element este ntr-o mulime i una care conine toate mulimile,
adic tocmai mulimea A. Cu alte cuvinte, numrul mulimilor dintr-o partiie este
ntre 1 i n.
Prin aceast condiie se evit situaia in care, de exemplu, vectorul sol reine
<1, 3, 1). Aceasta ar avea semnificaia c elementele 1 i 3 se gsesc in
submulimea 1 a partiiei, iar elementul 2 se gsete in submulimea 3 a partiiei. ln
acest caz, lipsete submulimea 2 a partiiei.
- sol=(l,1,l) - A1 =(1,2,3);
begin
write('n='); readln(n);
back(l);
end.
c > Toate soluiile sub form de vector ale problemei generrii tuturor partiii lor
mulimii A au lungimea n.
f Ordinea numerelor din sum este important . Astfel, se tiprete 11.2 dar
J;. i 211, 121.
sol[l]+sol[2]+ sol[k]~.
~~ie
[lo 1o o J1l1lo o 11111110
s=O,I<=l s=l,k =2 s=2,k::=3
~
s=3,k=4
'
Observaimodul in care ca lculm suma la fiecare pas. De cte
ori se trece
la componenta urmtoare (k+l) , las se adun sol
[kJ, de cte ori se face
pasul napoi (se trece la componenta k-1), din s se
scade sol [kl.
Programul este prezentat n continuare:
Varia nta Pasca l ' ' .., . .,. Vari a ni~ C++
var sol: array [1 . 100] of integ er; #incl ude <iost ream. h>
n,i,s :inte ger; int sol[lO O], n,i,s ;
proce dura back (k:in teger ); void back (int k)
begin
{ if {s===n )
if s=n then begin { for (i=l;i <==k -l;i++ )
for i:=l to k-1 do cout< <sol CiJ;
write (sol[ iJ); cout< <endl ;
write ln; }
end el se
else begin { sol[k ]=O;
sol[k ]:=O; while (sol[ k]+s <n)
while sol[k ]+s<n do ( sol[k ]++;
begin s+=s ol[k] ;
sol[k ] :=sol [kl+l ; back( k+l);
s:=s+ sol[k ]; back( k+l); s-=so l[k];
s: =s-so l[k]
end; }
end }
end;
main( )
begin
{ cout< <"n=" ; cin>> n;
write {'n= ') ; readl n{n);
back (l);
back{ l) }
end.
226 Capitolul 8. Metoda backtracking
~Exerciii
1. Cum trebuie procedat n cazul n care se cere ca soluiile s fie afiate o singur
dat? Spre exemplu, dac s-a afiat descompunerea 1,1, 2 s nu se mai afieze
2 , 1,1sau1, 2,1?
Indicaie: procedeul a mai fost ntlnit, de exemplu la generarea combinrilor.
Soluiile se vor genera n ordine cresctoare. Modificai programul n acest sens.
2. Adaptai metoda de rezolvare astfel nct s se genereze numai partiiile formate
din numere naturale distincte.
3. Adaptai metoda de rezolvare astfel nct s se genereze numai partiiile formate
din cel puin p numere naturale distincte (n i p citite de la tastatur).
4. Adaptai metoda de rezolvare astfel nct s se genereze numai partiiile formate
din numere naturale aflate n intervalul [a, bl (n, a i b citite de la tastatur).
5. Rezolvai problema scrierii numrului natural n ca sum de numere naturale
alese dintr-o mulime format din k valori date {v1, v2, ... , vk}. Astfel, 10 se
poate scrie ca sum de numere alese din mulimea {2,3,6} n felul urmtor:
10=2+2+2+2+2, 10=2+2+3+3,10=2+2+6.
O En un. Se dau suma s i n tipuri de monede avnd valori de a 1 ,a2 , ,a0 lei. Se
cer toate modalitile de plat a sumei s utiliznd aceste monede. Se presupune
c se dispune de un numr nelimitat de exemplare din fiecare tip de moned.
1) 1 de 2, 1 de 3; 2) 1 de 1, 2 de 2 ; 3) 2 de 1, 1 de 3;
4) 3 de 1, 1 de 2; 5) 5 de 1;
.11..~ Ce observm?
22 /
,,.anual de informatic pentru clasa a Xl-a
situaie corespunde
torului sol care rein o. Aceast
1. Exist componente ale vec ul. Din ace st motiv, fiecare
v nu este luat fn calc
:az ulu i n care mo ned a respecti are aflat naintea tuturor celo
r
component a vectorului
sol va fi iniializat cu o valo
oosibile, adic cu -1.
de tipuri de monede).
componente (n este numrul
2. Orice soluie are exa ct n t luate n calcul.
edele, chiar i cele care nu sun
Acest numr include toate mon
manen sum a obinut
la un
rioar, vom reine n per
3. Ca i la pro blem a ante
, avem la dispoziie suma:
moment dat. Astfel, la pasul k
l[k -1]
ol[ 2] + + a[k -l] *so
s a(l ]*s ol[ l] + a(2 ]*s
0 Rezol vare
2. Nu toate solui ile au aceeai lungime, ntruct exist trasee de lungime d iferit.
Se obine o soluie atunci cnd coordonatele camerei unde s-a intrat sunt n afara
matricei (nu au linia ntre 1 i m i nu au coloana intre 1 i n). Evident, atunci cnd
s-a gsit o situaie, aceasta se afi eaz.
3 Spunem c o camer este accesi bil dac exist intrare din camera curent
ctre ea. Atenie la modul (vedei programul) Tn care testm dac o camer este
accesibil sau nu. Este o operaie in care se testeaz conin u tul unui anumit bit.
Acesta se obine efectu nd un I logic intre dou valori. De exemplu, dac testm
i e irea spre sud , atunci efectum I logic ntre 0010( 21=2<lo> i valoarea reinut
n matrice pentru camera curent. Dac valoarea obinut este diferit de o, atunci
avem ieire din camera cu rent ctre sud.
4 . nainte de a intra ntr-o camer accesibil se testeaz dac respectiva camer
a mai fost vizitat sau nu. Pentru aceasta utilizm funcia vizitat. ln caz c a
fost vizitat, se face pasul inapoi.
Analizai programul:
Varianta Pa~cal
var sol : arr ay [1 100,1 . 2] of # include <iostream.h>
integer; int sol [100] [ 2] , 1 [10] [10],
l:array [0 . 10,0 . 10] of m,n, i,j,lin,col;
integer; i nt vizitat ( int k, int lin,
m,n,i , j,lin,col:intego r; int col)
function vizitat (k,lin, [ int v O;
col:integer):boo lean; for (i.,l;i<=k;i++)
begin if (sol [i] [O]==lin &&
vizitat: = false; sol [i] [l]a=col) val;
for i: =l to k-1 do 1 return v;
if (sol[i,l]=lin) and }
(sol[i,2]=col)
void tipar (int k,i nt lin,
then vizitat:=true; int col)
end; { cout <<" Solutie "<<end l. ;
procedura for (i.,1 ; i<=k-1;i++)
tipar(k,lin,col:i nteger); cout<<sol[i] [0] <<" "
begin <<sol [i] [1] <<e ndl;
writeln('Solutie '); if ( lino:nO)
for i: =1 to k-1 do cout<<"iesire prin nord"
writeln(sol [i , 1],' , <<endl ;
sol[i,2 ]); el se
if lin.. o then i f (lin==m+l)
writeln('ie sire prin nord ' ) cout<<"iesire prin sud"
el se <<endl;
if lin=m+l then el se
wri teln ( iesire pri n sud' ) if (col==O)
el se cout<< "iesire prin vest"
if col= O t:hen <<endl ;
writeln(' l esire prin vest') el se
el se cout<< "iesire prin est"
writeln( iesire prin est '); <<endl;
readln; }
end;
230 Capitolul 8. Metoda backtracking
~ Exerciii
1. Adaptai rezolvarea pentru un labirint Tn care fiecare csu reine valoarea 1
sau o (1 semnificnd csu plin , prin care nu se poate trece, iar o csu liber ,
pe unde se poate trece). Ca i in problema prezentat , deplasarea se poate face
dintr-o csu in orice alt csu alturat, orizontal sau vertical , cu condiia ca ea
s existe i s fie l iber. Val idai poziia iniial a omului (lin, col), astfel nct
aceasta s coresp und unei csue libere. Esti mai spai u l de memorie utilizat
in aceast vari a nt.
Varianta Pascal .
l' 1
.. ~, :.. ' ...;~ Varianta C+;+- , , .' , i, 1,.. :.!
var sol:array [1 100,1 3] #include <iostream .h>
of integer1
t:array [0 10,0 10] int sol[100] [3],t[10] [10],
of integer; m,n,i,j,l in,col1
m,n,i,j,l in,col:in teger;
procedur a t ipar(k:in teger); void tipar(in t k)
begi n { cout<<"S olutie "<<endl;
writeln( 'Solutie ); for(i=l;i< =k-1;i++ )
for i:=1 to k-1 do cout<<so l [i] [1] <<" "
writeln( sol [i, 2],' ', <<sol[i] [2]<<end l;
sol[i,J] )I
end; void b a ck(int k, i n t lin, int col)
procedur a { if (linu=O 1 1 lin==m+1 11
back(k,l in,col:in teger); col==O 1 1 col==n+1 )
begin tipar(k) l
if (lin=O) or (linm+1 ) or el se
(col=O) or (coln+1) { sol[k] [0 ]=0;
then tipar(k) sol [k) [1] =lin;
olse begin sol[k] [2) r:ocol;
sol[k,1]: =0; while (sol[k] [0)<4)
sol [k,2] :=lin; (
sol[k,J) :=col1 sol[k) [0]++;
while sol[k,1]< 4 do switch(s ol [k] [0])
begin {
sol[k,1J: =sol(k,1 ]+11 case 1:
case sol[k,l] of if(t[lin- 1] [col]<t[ lin] [col])
1:if t[lin-1,c oll< back(k+ l,lin-l,co l); break;
t[lin,co l] then case 2:
back(k+ 1,lin-1,c ol); i f(t[lin) [col+l]< t[lin] [col])
2:if t[lin,col +1]< back(k+ l,lin,col +l); break;
t[lin,co l] then case 3:
back(k+1 ,lin,col+ 1) J if(t[lin +l l [col)<t[l in] [col])
3:if t[lin+1,c ol]< back(k+1 ,lin+1,co l ); break;
t[lin,co l) then case 4:
back(k+ l,lin+1,c ol)J if (t [lin] [col -1] <t [lin] [col])
4:if t[lin,col -1]< back(k+ l,lin,col -1); break;
t[lin,co l) then )
_j
back(k+1 ,lin,col- 1); }
end1 {case} }
end end end; }
begin main ( )
write('M =')1 readln(m ); { cout<<"m ="; cin>>m;
write('N =')1 readln(n );
~~ cout<<"n ="; cin>>n;
~
Vanual de informatic pentru clasa a Xl-a 233
begin if (k=-n*n)
if k=n*n { for (i=l;i<=k-l;i++)
then cout<<sol[i] [0]<<" "
begin <<sol[i] [l]<<endl;
for i:=1 to k-1 do cout<<lin<<" "<<col;
writeln(st[i,1], ' ' exit(EXIT_SUCCES S);
st[i,2]); }
writeln(lin,' ,col); el se
halt; { sol[k] [O]=lin;
end sol[k] [l]=col;
el se for (i=O;i<=7;i++)
begin { linie=lin+x[i];
st[k,1] :=lin; coloana=col+y[i] ;
st[k,2] :=col; if (linie<=n && linie>=1
for i:=1 to 8 do
&& coloana<=n &&
begin
coloana>=l &&
linie:=lin+x[i];
t[linie] [coloana]==Ol
coloana:=col+y[i ];
{
if (linie<=nl and
t[linie] [coloana)=l;
(linie>=l) and
back(k+l,linie,co loana);
(coloana<=n) and
(coloana>=1) and t[linie] [coloana]=O;
}
(t[linie,coloana]g O)
}
then
}
begin
}
t[linie,coloana] :=1;
back(k+l,linie,
main()
coloana) 1
t [linie,coloana]:a O; { cout<<"n=";
end; cin>>n;
end back(1,1,1);
e .n d
end;
begin
write ('n=');
readln(n);
back(1,1,l);
end.
Vanual de informatic pentru clasa a Xl-a 235
Probleme propuse
10. Fiind dat un num~r natural pozitiv n, se cere s~ se produc la ieire toate
descompunerile sale ca sum de numere prime.
11. "AttUa i regele". Un cal i un rege se afl pe o tabl de ah. Unele cmpuri
sunt "arse", poziiile lor fiind cunoscute. Calul nu poate clca pe cmpuri "arse",
iar orice micare a calului face ca respectivul cmp s devin "ars" . S se afle
dac exist~ o succesiune de mutri permise (cu restriciile de mai sus), prin
care calul s poat ajunge la rege i s revin la poziia iniial. Poziia iniial
a calului, precum i pozi i a regelui sunt considerate "nearse".
12. Se dau n puncte n plan prin coordonatele lor. Se cer toate soluiile de unire a
acestor puncte prin exact p drepte, astfel nct mulimea punctelor de
intersecie ale acestor drepte s fie inclus n mulimea celor n puncte.
17. Se dau N puncte albe i N puncte negre n plan, de coordonate intregi. Fiecare
punct alb se unete cu cte un punct negru, astfel nct din fiecare punct, fie el
alb sau negru, pleac~ exact un segment. S~ se determine o astfel de
configuraie de segmente astfel nct oricare dou segmente s nu se
intersecteze. Se citesc N perechi de coordonate corespunznd punctelor albe
i N perechi de coordonate corespunznd punctelor negre.
' 9. O trup cuN actori ii propune s joace o pies cu A acte astfel nct:
20. Fiind dat un numr natural N i un vector v cuN componente ntregi, se cere:
24. Fiind date numele a n soldai , ce algoritm vom utiliza pentru a lista toate
grupele de cte k soldai? Se tie c ntr-o grup, ordinea prezint importan .
25. Fiind date n numere naturale, ce algoritm vom utiliza pentru a determina
eficient o submulime maximal de numere naturale distincte?
Indicaii
6. Dei
algoritmul este asemntor, nu este acelai, trebuie pus o condiie
suplimentar. De exemplu, in cuvntul "mama" nu se poate inversa a de pe poziia
2 cu a de pe poziia 4.
23. b)
24. a)
25. d)
Explicaie: primele dou variante prezint soluii exponeniale, a treia este n
o (nl >. Dar dac sortm numerele, atunci le putem afia pe cele distincte dintr-o
singur parcurgere. Sortarea se poate efectua in o (nXlog (n) ), iar parcurgerea
n O(n). Prin urmare, complexitatea este O(nXlog(n)).
26.d)
1. Se dau n orae. Unele dintre ele sunt unite prin osele directe (care nu mai
trec prin alt ora).
2. Se cunosc relaiile de prietenie dintre n persoane.
3. Se dau n ri i se cunoate relaia de vecintate ntre ele.
4. Se dau n triunghiuri, iar unele dintre ele sunt asemenea.
V= {1,2 1 3 ,4,5,6};
E = {(1,2), (1,3), (1,5), (2,3), (3,4),
(4,5)}
Observaii
./ Dou noduri distincte pot fi unite prin cel mult o muchie. n exemplul de
mai sus, <1., 2) este muchia care unete nodul 1 cu nodul 2. Dac scriem
(2,1.), ne referim la aceeai muchie (perechea este neordonat) .
Definiia este restrictiv, n unele lucrri vei ntlni definiii mai puin restrictive, de
1
Definiia 9.3. ntr-un graf neorientat, prin gradul unui nod v se nelege
numrul muchiilor incidente cu nodul v i se noteaz cu d(v). Un nod
cu gradul o se numete nod izolat, iar unul cu gradul 1 se numete nod
terminal.
O relaie util: fie un graf neorientat cun noduri i m muchii. Dac notm cu d1,
dl .... , a., gradele celor n nodu,i, atunci avem relaia:-
" d1 +d 2 +d 3 +.~d-:-=2m.l
~ Demonstraie: fiecare muchie face s creasc gradele celor dou noduri la
care este incident cu cte o unitate. Prin urmare, se obine re l aia anterioar.
- fie afirmaia: nodul i este izolat. Pentru exemplul 1., nseamn c nu exist nici
o osea care leag oraul i cu alt ora, pentru exemplul 2 ., nseamn c
persoana i nu are nici un prieten, pentru exemplul 3 ., nseamn c ara i nu se
nvecineaz cu nici o ar (este situat pe o in su l), pentru exemplul 4., nseamn
c nu exist nici un triunghi dintre celelalte n-1 triunghiuri care s fie asemenea cu
triunghiul i.
~ Exerciiu
Dai un exemplu inspirat din viaa real, pentru care s gsii graful asociat.
Astfel, vei rspunde la ntrebrile: ce semnificaie a~ nodurile sau muchiile i ce
nseamn gradul unui nod.
242 Capitolul 9. Introducere n teoria grafurilor
n acest paragraf, prezentm principalele structuri de date prin care grafurile pot
fi memorate n vederea prelucrrii lor. De la nceput, precizm faptul c vom alege o
structur sau alta n funcie de2 :
a) algoritmul care prelucreaz datele referitoare la graf;
Pentru fiecare structur de date pe care o vom folosi, vom avea cte o
procedur (funcie) care citete datele respective. Toate aceste subprograme se
gsesc grupate n unitatea de program grafuri .pas (pentru Pascal) i n
grafuri. cpp (pentru C++). Vom fi astfel scutii ca, pentru fiecare program pe care l
realizm, s fim nevoii s adugm liniile de cod necesare citirii i ne permite s ne
concentrm exclusiv asupra algoritmului.
0 Fiierul text:
1
1
1
3
5
2
2 3
3 4
Figura 9.3.
4 5
Exemplu de graf neorientat
a .. =
I,J
{1,O, pentru {i, j) e E
pentru (i, j) ~ E
2
Modul de alegere a structurii il vei inelege pe parcursul studiului acestui capitol.
~ianual de informatic pentru clasa a Xl-a 243
o o 1
1 1 o
1 o 1 o o o
1 1 o 1 o o
A6.6 =
o o 1 o 1 o
1 o o 1 o o
o o o o o o
(:1, Observaii
1 . ntruct, din modul n care a fost definit graful, rezult c nu exist muchii de la un
nod la el nsui, rezult c elementele de pe diagonala principal rein o:
6 . Dac graful citit are un numr mic de muchii, atunci matricea de adiacen este o
form ineficient de memorare a lui, pentru c ea va reine o mulime de o.
#include grafuri.cpp"
int A[50] [50],n;
n,i , j:integer; main()
begin {
CitireN( Graf. txt ,A, n); CitireN("Graf . txt",A,n);
for i:=1 to n do for (int i=1;i<-n;i++)
begin { for (int ja1;j< n;j++)
for j:=1 ton do cout<<A[i] [j]<< ;
write (A[i,j], ') ; cout<<endl;
writeln; }
end; }
end.
0 1 -> 2,3,5
2 -> 1 , 3
3 -> 1,2,4
4 - ~ 3,5
5 -> 1,4
6 ->
Figura 9.4.
Manual de informatic pentru clasa a Xl-a ~45
Start 15 17 19 l11l12l O 1
1 2 3 4 5 6 7 8 9 10 11 12
T[O] 2 1 3 1 5 1 3 2 4 3 5 4
T [1] o o 1 o 3 o 2 4 8 o 10 6
4 Exemplu de utilizare
Dorim s vedem care este lista nodurilor adiacente cu nodul 3. Start [3] =9,
adic lista ncepe n coloana 9 a matricei T. Primul nod adiacent cu nodul 3 este 4.
Urmtorul se gc':!lsete la indicele a. Urmtorul nod adiacent cu nodul 3 este nodul 2.
Urmtorul se gsete la indicele 4. Acesta este nodul 1 . El este ultimul din list,
pentruT(1,4)=0 (T[l] [4)).
Con siderm primul caz, n care vom pune pe j, ca prim element n lista
nodurilor adiacente cu i. Variabila k, care are iniial valoarea o, va reine indicele
ultimei coloane din T completat. O astfel de operaie se realizeaz n patru pai:
.~ -
!
':- . ~~
Programul urmtor citete datele despre un graf i afieaz, pentru fiecare
..... . nod, lista nodurilor adiacente:
Mai jos, putei observa cum se descrie un vector (v) care reine muchiile
unui graf:
S considerm mulimea elevilor unei clase. Teoretic, oricare doi elevi din
clas se cunosc. Pentru a transpune n limbaj specific teoriei grafurilor aceast
situaie, vom considera c fiecare elev este un nod al grafului. Pentru c oricare doi
elevi se cunosc, nseamn c oricare dou noduri sunt unite printr-o muchie.
Astfel, am obinut un graf aparte, pe care-I vom numi graf complet.
Definiia 9.4. Prin graf complet vom nelege un graf neorientat n care
oricare dou noduri sunt adiacente. Vom nota un graf complet prin K", unde
n este numrul de noduri ale grafului.
248 Capitolul 9. Introducere n teoria grafurilor
Figura 9.5.
Exemplu de graf complet
Relaii utile:
1. ntr-un graf complet, gradul oricrui nod este n-1. Evident, din fiecare nod,
pleac (sosesc) n-1 muchii.
n(n -1)
2. ntr-un graf complet, avem relaia: m = , unde m este numrul de
2
muchii, iar n, numrul de noduri.
n(n - 1)
., 2
.r
i corespunde unui graf complet. Se tie c, fiind dat o mu~ime A cun elemente,
avem 2n submulimi disjuncte ale acesteia (aici este inclus i submulimea vid
i A). Prin urmare, avem:
n(n - 1)
2- 2-
submulimi ale numrului maxim de muchii. Ori, fiecrei submulimi de muchii i
corespunde un graf nemientat, pentru c nodurile sunt aceleai.
f, Un graf parial al unui graf dat, este el nsui sau se obine din G prin
suprimarea anumitor muchii. Privii exemplul de mai jos:
Figura 9.6.
Obinerea unui
graf parial
--->
rezult
G={V,E)
2. Fiind date n orae, unele dintre ele sunt unite printr-o osea direct (care nu mai
trece prin alte orae). Asociem situaiei date un graf G. Datorit precipitaiilor, anumite
osele se inund i nu mai pot fi utilizate. Aceasta nseamn c 1'n G se suprim
anumite muchii i se obine un graf parial G .
lli Definiia 9.6. Un subgraf al unui graf neorientat G.., .<v, E) este un graf
:.I!.) G1 .. (V11 E1), unde v1cv. E1c::E, iar muchiile din E 1 sunt toate muchiile din
' E care sunt incidente numai la noduri din mulimea v 1 .
( ., Un s~bgraf al unui graf G este el nsui sau se obine din G prin suprimarea
anumttor noduri i a tuturor muchiilor incidente cu acestea. Privii exemplul de
mai jos:
Figura 9.7.
Obinerea unui
subgraf
--->
rezult
G= (V,E)
250 Capitolul 9. Introducere n teoria grafurilor
1. Se dau n firme. ntre unele din acestea se stabilesc relaii de colaborare. Asociem
situaiei date un graf G. intre timp, anumite firme se desfiineaz . Aceasta inseamna
c n G vom elimina anum ite noduri i muchiile incidente lor, obinnd un subgraf al
luiG, G1.
2 Mai multe calculatoare (n) sunt legate n reea cu ajutorul unor cabluri. Asociem
situaiei date un graf G. ntre timp, anumite calculatoare se defecteaz. Astfel, se
obine un subgraf al lui G, G1 .
-+ Vizitm apoi toate nodurile adiacente cu el fie ele j 1, j 2, ... jk, vizitate n
aceast ordine.
3
n acest paragraf vom exemplifica parcurgerile doar in cazul grafurilor conexe. Cum
noiuneanu a fost prezentat pn n acest moment. precizm doar c vom exemplifica
parcurgerea grafurilor n care oricare dou noduri sunt "legate printr-o succesiune
de muchii.
Manual de informatic pentru clasa a Xl-a 251
Nod pornire 1: 1 3 6 2 7 5 4
Nod pornire 3: 3761254
Nod pornire 6: 6 3 1 7 2 5 4
Figura 9.8.
bag in
CitireN('Graf.txt' , A, n);
bf(l);
end.
1
Figura 9.9.
254 Capitolul 9. Introducere n teoria grafurilor
9.1. 7. Lanuri
Definiia 9.7. Pentru graful neorientat G= (V, E), un lan L=[v1 ,v2 ...vp]
este o succesiune de noduri cu proprietatea c oricare dou noduri vecine
sunt adiacente, adic (v1 ,va)EE, (v;r,v3)EE, ... , (vp_1 ,vp)EE. De
altfel, un lan poate fi definit prin succesiunea de muchii (v1 , va) EE, (v2 , v 3 ) EE, ... ,
(Vp-ltVp)EJ!!.
Definiia 9.8. Se numete lan elementar un lan care conine numai noduri
distincte.
Figura 9.1 O.
O Problema 9.1. Fiind dat un graf i dou noduri ale sale a i b, s se scrie un
program care decide dac ntre ele exist un lan sau nu, iar n caz c acest lan
exist, se cere s se afieze lanul.
. {j,
T[1] =
dac i este descendent al lui j
O, dac i nu a fost selectat
S
mai observm c un nod este selectat o singur dat, deci, n final, T va
reine, pentru fiecare nod i, nodul j de la care a fost selectat. Pentru nodul de la care
a pornit parcurgerea (a) vom avea T (a) = O, pentru c acest nod nu a fost selectat de
algoritm. De aici, rezult c drumul poate fi reconstituit, pornind de la T, astfel: se
afieaz b, apoi T [b) , apoi T [T [b) ) ... pn cnd se obin e valoarea o. Pentru ca
drumul s nu fie afiat n ordine inve rs fa de modul n care a fost obinut ,
subprogramul refac care l reconstituie i l afieaz este recursiv. Programul de mai
jos afieaz drumul, pornind de la matricea de adiacen a grafului:
,
if (T[b]<>O) then refac(b); if (T[b]taO) refac(b);
end. }
1. S observm c vectorul T poate fi folosit pentru a obine lanuri de la nodul a la
oricare alt nod al grafului.
2 Dac refacem rezolvarea prin utilizarea parcurgerii n lime, vom observa c
lanu l obinutare lungimea minim . Prin natura ei, parcurgerea BF selecteaz nodurile
n ordinea "depl1rii" lor fa de nodul de la care a nceput parcurgerea. Astfel, la
inceput se viziteaz primul nod (a), apoi nodurile pentru care lungimea lanului de la a
la ele este 1, apoi nodurile pentru care lungimea lanului de la a la ele este 2, .a.m.d.
.... ;t "'
Varianta Pascal
uses grafuri; #include "grafuri.cpp"
var int n,coada[50],s[50],
n,al,b,i_c,sf_c,i:integer ; i_o=l, sf_ c ..l,
s,T,coada : array[l . SO] of A(SO] [50] ,i,T[SO] ,a,b;
integer;
A:mat_ ad; void refac (int nod)
{ i f (nodi=O)
procedura refac (nod:integer); {refac (T[nod]);
begin cout<<nod<<" ";
if nod<>O then }
begin }
refac (T[nod]);
write (nod, ' ');
end
end;
258 Capitolul 9. Introducere n teoria grafurilor
a) pentru exemplul 1, ntrebarea este: cum putem afla, pentru fiecare ora n parte,
oraele n care putem ajunge cu maina?
b) pentru exemplul 4, ntrebarea este: cum putem afla, pentru fiecare triunghi n
parte, care sunt triunghiurile asemenea cu el?
{~.
dac exist lan de la i la j
L(i,j) = 'in caz contrar
IAanual de informatic pentru clasa a Xl-a 259
:J Problema 9.2. Fiind dat un graf G, cum putem obine matricea lanurilor?
~ Rspunsul este uor de dat. Parcurgem graful ncepnd cu nodul1. Pentru toate
-odurile j vizitate, vom avea L <1, j ) =1, completnd astfel prima linie a matricei.
;poi, vom parcurge din nou, graful, pornind de la nodul 2. Pentru toate nodurile j,
:izitate, vom avea L(2, j) =1, apoi parcurgem graful ncepnd cu nodul 3 .... .a.m.d.
O anumit mbuntire a algoritmului se obine dac inem cont de faptul c matricea
~urilor este simetric (de ce?). Lsm ca exerciiu scrierea acestui program.
1trebare: care este complexitatea acestui algoritm?
Definiia 9.9. Un graf neorientat G= (V, E) este conex, dac pentru orice
pereche de noduri x, yeV, exist un lan n care extremitatea iniial este x
i extremitatea final este y.
1,~,
,~j Un graf cu un singur nod este, prin definit,ie, conex. Aceasta pentru c nu exist
dou noduri diferite pentru care s se pun problema existenei unui lan.
260 Capitolul 9. Introducere n teoria grafurilo
O Problema 9.3. Fiind dat un graf Go: (V, E >, s se scrie un program care s decid
dac graful dat este sau nu conex.
0 Rezolvare. innd cont de cele nvate, problema nu este grea. Putem utiliza
una din metodele de parcurgere nvate, DF sau BF. Ideea este urmtoarea: dac ,
pornind de la un nod, printr-una din metodele de parcurgere, ajungem s vizitm toate
celelalte noduri, atunci graful dat este conex. Cum putem ti dac am vizitat toate
nodurile? Simplu, dup parcurgere, toate componentele vectorului s rein 1. Pute1
scrie acest program?
Fie graful asociat unuia dintre cazurile prezentate. n termeni din teoria
grafurilor, problema se reduce la determinarea nodurilor unei componente conexe.
$i': Exemple
Figura 9.14.
2. Graful din figura 9.14. conine 3 componente
conexe. Aa cum un graf, cu un singur nod, este
conex, tot aa un nod izolat alctuiete el singur o
G
component conex.
0
Manual de informatic pentru clasa a Xl - a 261
.~ Observaii
'")
'r>
1 . Cte componente conexe poate avea un graf neorientat cun noduri? Numrul
lor este cuprins ntre 1, pentru un graf conex i n corespunztor unui graf cu toate
nodurile izolate.
0 Rezolvare. Dup cum uor v putei da seama, o parcurgere a grafului (DF sau
BF) pornind de la un anumit nod, viziteaz toate nodurile componentei conexe care
l conin e . Pentru fiecare nod vizitat, s [il reine 1. Dac, dup o parcurgere, mai
rmn noduri nevizitate, parcurgerea se reia ncepnd de la primul nod nevizitat.
Evident, numrul componentelor conexe este egal cu numrul de parcurgeri
necesare pentru a fi vizitate toate nodurile.