Sunteți pe pagina 1din 20

4.

Structura de date sir


4.1 TDA sir
 I MM: secventa finita de caractere c1, c2,…, cn ; n -> lungimea
secventei; n=0  sir vid
 II Notatii : s, sub, u – siruri
c – valoare de tip caracter
b - boolean
poz, lung – intregi pozitivi
 III Operatori: CreeazaSirVid(s) InsereazaSir(sub, s, poz)
SirVid(s)-> b FurnizeazaCar(s, poz)->c
SirComplet(s)->b AdaugaCar(s, c)
LungSir (s)->lung StergeSubsir(sub, s,poz)
Pozitie (sub, s)->poz StergeToateSubsir(sub,s)
Concat (u, s) StergeSir(s, poz, lung)
CopiazaSubsir(u,s,poz, lung)
Operatorii: implementati in termenii limbajului de programare
(primitivi) sau dezvoltati de programator

SDA curs 9 I IS 2009/2010 1


4.2 Implementarea TDA sir
4.2.1 Implementarea cu tablouri
- articol format dintr-un intreg ( lungimea sirului) si un tablou de caractere
#define LungMax …
typedef int TipLungime; /*0… LungMax*/
typedef int TipIndice; /* 1…LungMax*/
typedef char tab[LungMax];
typedef struct{
TipLungime lungime;
tab sir;
}TipSir;
TipSir s;
Ex.: Creeaza_Sir_Vid(TipSir s);Lung_Sir (TipSir s);Adauga_Car(TipSir s);  O(1)
Copiaza_Subsir(TipSir u,TipSir s, TipIndice poz, TipLungime lung);O(n)
Implementare simpla, operatori performanti, dar cu o utilizare ineficienta a
spatiului de memorie
SDA curs 9 I IS 2009/2010 2
4.2.2 Implementarea tipului sir prin tabele
 Toate sirurile utilizate la un moment dat se pastreaza intr-un singur tablou
numit Heap.
 Se asociaza o tabela auxiliara (tablou auxiliar) care pastreaza evidenta
sirurilor, numita tabela de siruri; o locatie in tabela de siruri refera un sir
printr-un articol compus din 2 elemente:
- lungimea sirului curent
- un indicator in HEAP care precizeaza pozitia ( inceputul) sirului
#define LungimeHeap …
#define LungimeTabela …
typedef struct{
int lungime; /* 1…LungimeHeap*/
int indicator; /* 1…LungimeHeap*/
}ElemTablou;
Typedef int TipSir;

SDA curs 9 I IS 2009/2010 3


typedef ElemTablou tab1[LungimeTabela];
typedef char tab2[LungimeHeap];
tab1 TabelaDeSiruri;
tab2 Heap;
int Disponibil;
int NumarDeSiruri;
 Lungimea limitata a sirurilor complica operatorii de tip adaugare caracter,
stregere subsir, etc. noi instante ale sirurilor implicate la sfarsitul tabloului
Heap
 Copierea unui sir sursa intr-un sir destinatie se obtine prin pozitionand campul
indicator al destinatiei spre indicatorul sirului sursa in Heap economie de
memorie; complica operatia de stergere

SDA curs 9 I IS 2009/2010 4


4.2.3 Implementarea sirurilor cu pointeri

 Se bazeaza pe reprezentarea sirurilor drept o colectie de celule


inlantuite, fiecare celula continand unul sau mai multe caractere
 Accesul la caracterele sirului de face doar secvential
typedef struct cel{
char ch;
struct cel* urm;
}Celula;
typedef Celula* PointerCelula;
typedef struct{
int lungime;
PointerCelula cap, coada;
TipSir s;
 Se utilizeaza in special cand lungimea sirurilor este imprevizibila

SDA curs 9 I IS 2009/2010 5


4.3 Tehnici de cautare in siruri
4.3.1 Cautare tabelara

 Pentru a stabili coincidenta a doua siruri e necesar sa se stabileasca


coincidenta tuturor caracterelor corespunzatoare din sirurile comparate
#define M …
typedef char sir[M];
sir x,y;
x==y  A j: 0 <= j < M : x j == y j
 Lungimea unui sir poate fi precizata explicit (implementarile anterioare)
sau implicit, prin precizarea unui caracter fanion care sa marcheze
terminarea sirului
 Cautarea tabelara parcurge un tablou de siruri, pentru fiecare intrare in
tablou verificand prezenta sirului cautat x prin aplicarea tehnicii de
cautare liniara; in cazul unui terminator de sir coincidenta apare daca
ultimul caracter identic este terminatorul de sir
 Structuri imbricate

SDA curs 9 I IS 2009/2010 6


4.3.2 Cautarea directa in siruri

 Are drept scop stabilirea pozitiei primei aparitii a sirului p in sirul s; rezultatul
cautarii este indicele i al primei aparitii
char s[N];
char p[M]; /* M<<N*/
 Precizarea coincidentei se face cu P(i,j):
P(i,j) A k: 0 <= k < j : s i+k == p k
In cazul in care P(i,j) este adevarat, avem o coincidenta de j caractere
incapand cu pozitia i in sirul s; pentru a avea o coincidenta pe lungimea M este
necesar sa fie adevarat P(i, M)
 Precizarea primei aparitii se face cu Q(i):
Q(i) A k : 0 <= k < i : ~P(k, M)
 Cautarea directa lucreaza destul de repede daca se presupune ca nepotrivirea
dintre s si p apare dupa cel mult cateva comparatii O(N)
 Cel mai defavorabil caz este cand nepotrivirea dintre s si p apare totdeauna pe
ultimul caracter din p  O(N*M)
 Eficienta scazuta: modelul p avanseaza cu o singura pozitie dupa o nepotrivire

SDA curs 9 I IS 2009/2010 7


4.3.3 Cautare Knuth-Morris-Pratt

 Cautarea directa nu tine cont de informatiile rezultate din parcurgere


 O avansare mai rapida a modelului p in raport cu sirul s se poate obtine
pornind de la observatia: dupa o potrivire partiala a modelului cu sirul in care
se face cautarea, se cunoaste partial sirul s (zona parcursa deja) si daca
avem cunostinte apriorice asupra structurii modelului, obtinute printr-o
preprocesare (precompilare) a acestuia, se poate decide deplasarea pe o
distanta mai mare a modelului
 Preprocesarea modelului consta in identificarea pentru fiecare valoare a
indicelui j a celei mai lungi secvente de caractere care precede pe j si care se
potriveste cu o secventa situata la inceputul modelului; lungimea aceasta (cea
mia mare) se noteaza cu d j
 Daca d j < j atunci atribuirea j=d reprezinta o deplasarea modelului spre
dreapta cu j-d pozitii
 Se vor utiliza notatiile P(i-j, j) si Q(i-j), in care i indica lpozitia finala ( locul in
care s-a ajuns cu testarea coincidentei)

SDA curs 9 I IS 2009/2010 8


 In preprocesarea modelului se identifica situatiile particulare:
- nu exista subsiruri identice
- modelul este format din doua subsiruri identice (concatenate)  se
poate realiza avansul peste intreaga lungime a modelului ( d j =0)
- modelul nu contine subsiruri identice, iar ultimul caracter coincide cu
primul caracter  se poate executa avansul peste intreaga lungime a
modelului +1 caracter ( d j =-1)
 Cuatarea KMP conduce la beneficii numai daca in procesul de cautare
se gasesc potriviri partiale pe o anumita lungime a modelului
 Performanta la medie este O(N+M)
 Are avantajul ca procesul de cautare nu revine

SDA curs 9 I IS 2009/2010 9


4.3.4 Cautare Boyer- Moore

 Se bazeaza pe ideea de a incepe comparatia dintre modelul p si sirul s,


incepand cu ultimul caracter a modelului
 In cazul unei nepotriviri se va deplasa modelul astfel incat cel putin un caracter
sa coincida, respectiv sa fie o coincidenta intre caracterul din s corespunzator
ultimului caracter din p din pasul precedent de cautare si prima aparitie a acelui
caracter in model, prin parcurgere de la sfarsit
 Precompilarea modelului va tine cont de “distanta” in numar de caractere fata
de sfarsitul modelului; este necesar un tablou suplimentar d avand dimensiunea
setului de caractere utilizat, in care se notreaza cu d x distanta intre cea mai din
dreapta aparitie a lui x in model si sfarsitul modelului
 Pentru caracterele care nu apar in model in tabela d se completeaza lungimea
integrala amodelului
 Cautarea se termina cand j=0 sau i>N
 La medie , C< N; cazul cel mai favorabil conduce la nr. de treceri N/m

SDA curs 9 I IS 2009/2010 10


Cap. 5 Recursivitate
5.1 Preliminarii
 Caracteristica recursivitatii: posibilitatea de a defini un set infinit de obiecte
printr-o relatie sau un set finit de relatii
 Definitie recursiva: un obiect se defineste ca parte a propriei sale definiri
Ex. numerele naturale: 1 este un numar natural; succesorul unui numar natural
este un numar natural
 Utilizare alg. recursivi: definitii recursive; functii sau structuri de date
definite recursiv; solutii recursive
 Solutia unei probleme este recursiva daca in urma descompunerii top-down
oricare dintre problemele astfel rezultate este identica ca structura cu
problema initiala
 Iteratia este executia repetata a unei portiuni de program, atat timp cat o
conditie testata la sfarsit este indeplinita.
 Recursivitatea este executia repetata a unei portiuni de program, conditia
fiind verificata in timpul executiei programului
 Recursivitate: simpla ( directa) sau indirecta
SDA curs 9 I IS 2009/2010 11
 Conditia necesara si suficienta pentru ca un limbaj de programare sa
permita exprimarea sintactica a recursivitatii, este sa contina structuri
modulare de program ( functii sau proceduri) care sa poata fi apelate
prin nume si lista de argumente.
 Unei astfel de proceduri sau functii i se asociaza un set de obiecte
locale plus parametrii de apel, care impreuna formeaza contextul
apelului. La fiecare apel recursiv se creeaza un nou context
caracteristic apelului, care este salvat in stiva. Intotdeauna
identificatorii se refera la setul de variabile cel mai recent creat.
 Un program recursiv P poate fi exprimat printr-o multime P astfel:
P = P[ Si, P]
 Formal, recursivitatea trebuie sa fie finita, fiind necesar un parametru:
P= daca B atunci P [ Si, P]
P= P [Si, daca B atunci P]

SDA curs 9 I IS 2009/2010 12


 Finitudinea unui algoritm poate fi demonstrata dovedind ca P deteremina
descresterea unei functii f(x), conditia de terminare a recursivitatii fiind
f(x)<=0
Ex. P(n)=daca n>0 atunci P [Si, P(n-1)]
P(n)=P [Si, daca n>0 atunci P(n-1)]
 E necesar ca numarul apelurilor recursive sa nu conduca la depasirea
capacitatii stivei
Ex. traversare lista, turnurile din Hanoi
 Verificarea unui program recursiv;
- demonstratie formala; presupune o verificare inductiva
- testarea exhaustiva a tuturor situatiilor ( cazurilor) posibile

SDA curs 9 I IS 2009/2010 13


5.2 Utilizarea si eliminarea recursivitatii

Utilizare Ex. : calculul factorialului


P=daca i<n atunci ( i=i+1;f=i*f;P )

f i+1=f i*(i+1)
i=0; f 0= 1 ; 0!=1; n!=n*(n-1)!
Eliminare
- recursivitate de sfarsit: apelul recursiv este ultima instructiune; se
inlocuieste apelul cu o bucla de iteratie simpla
P(n)=P [ Si, daca B atunci ( n=n-1; goto P)]
- Reursivitate normala
P(x)=P [Si, daca B atunci P(y), Sj]
programatorul gestioneaza stiva in care se salveaza contextul apelului

SDA curs 9 I IS 2009/2010 14


5.3 Tipuri de algoritmi recursivi

5.3.1 Alg. care implementeaza definitii recursive

Ex. factorial, sirul primelor n numere naturale, transformarea expresiilor din


format infix in format postfix, alg lui Euclid etc

int f_cmmdc ( int n, int m)


{
int cmmdc;
if (n==0) cmmdc=m;
else cmmdc= f_cmmdc(n, m%n);
return cmmdc;
}

SDA curs 9 I IS 2009/2010 15


5.3.2 Alg. de divizare (“divide et impera”)

 O problema de complexitate n se descompune in mai multe prbleme a caror


rezolvare este mai simpla rezultand solutii partiale, din care se determina
(recompune) solutia finala
rezolva ( problema x)
{
daca x este divizibil in subprobleme atunci
{
divide pe x in subproblemele x1, x2,…,xm;
rezolva(x1); rezolva(x2);,…rezolva(x m);
se combina solutiile partiale intr-o solutie pentru x;
}
altfel
rezolva direct pe x;
}
Ex. determinarea valorilor extreme ale unui vector

SDA curs 9 I IS 2009/2010 16


int a [100];
int mic, mare;
domeniu(int i, int j, int j, int *mic, int *mare )
{
int mijloc, mic1, mare1, mic2, mare2;
if (j<=i+1)
{
if(a[i]<a[j])
{
*mic=a[i];
*mare=a[j];
}
else
{
*mic=a[j];
*mare=a[i];
}
} SDA curs 9 I IS 2009/2010 17
else
{
mijloc=(i+j)/2;
domeniu(i, mijloc, &mic1, &mare1);
domeniu(mijloc+1, j, &mic2, &mare2);
if(mare1>mare2)*mare= mare1;
else *mare=mare2;
if(mic1<mic2) *mic=mic1;
else *mic=mic2;
}
}

SDA curs 9 I IS 2009/2010 18


5.3.3 Alg. de reducere

 reducerea gradului de dificultate a problemei pas cu pas, pana cand ea


devine banala; se revine recursiv si se asambleaza solutia problemei initiale
Ex. determinarea permutarilor primelor n numere naturale
- solutie: fixam un element si permutam celelalte n-1 elemente pana cand
se ajunge la 1 element ( permutare banala)
- aplicarea ordonata a alg. conduce la evidentierea celor n! permutari
permutari ( int k)
{
if(k==1)
afiseaza permutarea
else for (i=1;i<=k;i++){
a[i]<->a[k];
permutari(k-1);
a[i]<->a[k];
}
}
SDA curs 9 I IS 2009/2010 19
5.3.4 Alg. pt. determinarea tuturor solutiilor unei probleme

 Reliefeaza proprietatea algoritmilor recursivi de a evidentia in mod ordonat


toate posibilitatile referitoare la o situatie data; din multimea acestor
posibilitati se vor selecta acelea care prezinta interes
Ex. sectionarea firului de lungime l in parti de lungime 1 sau 2, in toate modurile
posibile; n=1 cazul banal; n=0 conditia de terminare
P( int n)
{
if(n>1){
se taie o bucata de lungime 1;P(n-1);
se taie o bucata de lungime 2;P(n-2);
anulare taietura /*presupune revenire*/
}
else{
if(n==1)
se taie o bucata de lungime1
afisare solutie
}
}
SDA curs 9 I IS 2009/2010 20

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