Sunteți pe pagina 1din 19

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 INFO 2015/2016 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 INFO 2015/2016 2
Adauga_Caracter(TipSir s, char c) O(1)
{ if ( s.lungime==Lung Max)
printf(“\n depasire lungime maxima “);
else
{
s.lungime=s.lungime+1;
s.sir[s.lungime]=c;
}
}

SDA curs 9 I INFO 2015/2016 3


Copiaza_Subsir(TipSir u, TipSir s, TipIndice poz, TipLungime lung)
{
TipIndice indexSursa, indexCopiere;
if( ( poz<1)||(poz>s.lungime) u.lungime=0;
else
{ indexSursa=poz+1;indexCopiere=0;
while ((indexSursa<S.lungime)&&(indexCopiere<lung))
{
indexSursa=indexSursa+1;
indexCopiere=indexCopiere+1;
u.sir[indexCopiere]=s.sir[indexSursa];
}
u.lungime=indexcopiere;
}
}
SDA curs 9 I INFO 2015/2016 4
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 INFO 2015/2016 5


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,
stergere subsir, etc. noi instante ale sirurilor implicate la sfarsitul tabloului
Heap
 Copierea unui sir sursa intr-un sir destinatie se obtine pozitionand campul
indicator al destinatiei spre indicatorul sirului sursa in Heap economie de
memorie; complica operatia de stergere

SDA curs 9 I INFO 2015/2016 6


Adauga_caracter(TipSir s, char c)
{
int i, lungimeVeche, indicatorVechi;
if ( (s<1)||(s>NumardeSiruri))
printf(“\n Referinta invalida”);
else
{
lungimeVeche=Tabela deSiruri[s].lungime;
indicatorVechi=TabelaDeSiruri[s].indicator;
for (i=0;i<=lungimeveche-1;i++)
Heap[Disponibil+i]=Heap[indicatorVechi+i];
Heap[Disponibil+lungimeveche]=c;
TabeladeSiruri[s].indicator=Disponibil;
TabeladeSiruri[s].lungime=lungimeVeche=1;
Disponibil=Disponibil+lungimeVeche+1;
}
}

SDA curs 9 I INFO 2015/2016 7


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;
TipSir s;
 Se utilizeaza in special cand lungimea sirurilor este imprevizibila

SDA curs 9 I INFO 2015/2016 8


Adauga_Caracter(TipSir s, char c)
{
if(s.lungime==0)
{
s.cap=malloc(sizeof(Celula));
s.cap->ch=c;
s.cap->urm=NULL;
s.coada=s.cap;
}
else
{
s.coada->urm=malloc(sizeof(celula));
s.coada->urm->ch=c;
s.coada->urm->urm=Null;
s.coada=s.coada->urm;
}
s.lungime=s.lungime+1;
}

SDA curs 9 I INFO 2015/2016 9


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 INFO 2015/2016 10


i=0;
while((x[i]==y[i])&&(x[i]!=‘\0’))i=i++;
Invariant: Aj:0<=j<i:x j=yj!=‘\0’
Conditie terminare: ((xi!=y i)||(xi==‘\0\))&&(Aj: 0<=j<I : x j=y j!=‘\0’)
Aceasta conditie stabileste coincidenta intre x si y daca pentru valoarea finala
a lui i avem x[i]=y[i]=‘\0’, respectiv inegalitatea celor doua siruri x<y sau x>y
dupa cum x[i]<y[i] sau x[i]>y[i]. Aceasta metoda se poate utiliza si cand
sirurile sunt de lungime inegala (codul terminatorului de sir trebuie sa fie mai
mic decat orice caracter reprezentabil
Tablou de siruri:
#define M …
#define N …
typedef char sir[M];
typedef sir tab[N]; /* N suficient de mare */
sir x; tab t;
SDA curs 9 I INFO 2015/2016 11
Cautare tabelara sir x in tabloul t , daca acesta este ordonat lexicografic:
….
s=0; d=N;
while (s<d){
m=(s+d)/2; i=0;
while ((t[m][i]==x[i]) && (x[i]!=‘\0’)) i=i++;
if(t[m][i]<x[i]) s=m+1;
else d=m;
}
if(d<n){
i=0;
while ((t[d][i]==x[i]) && (x[i]!=‘\0’)) i=i+1;
}
…..
/ * poz=d;
return((d<n)&&t[d][i]=x[i]));*/

SDA curs 9 I INFO 2015/2016 12


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 INFO 2015/2016 13


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
mai mare) se noteaza cu d j
 Daca d j < j atunci atribuirea j=dj reprezinta o deplasarea modelului spre
dreapta cu j-dj pozitii
 Se vor utiliza notatiile P(i-j, j) si Q(i-j), in care i indica pozitia finala ( locul in
care s-a ajuns cu testarea coincidentei)

SDA curs 9 I INFO 2015/2016 14


 In preprocesarea modelului se identifica situatiile particulare:
- nu exista subsiruri identice  se poate realiza avansul peste lungimea
verificata deja ( d j =0)
- 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)
 Cautarea 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 INFO 2015/2016 15


Cautare Knuth-Morris Pratt

s[0], s[1]…, s[i-j], s[ ], … ,s[i], … s[N-1]


p[0], p[1], … ,p[j], …p[M-1]
P(i-j, j) si Q(i-j)
i=0;j=0;
while ((j<M)&&(i<N))
{
while ((j>=0)&& (s[i]!=p[j])) j=d[j];
i=i+1;j=j+1;
}
Ex s …ABCD… s …ABCD…
p ABCE… j=3; dj=0 p ABCE…

s …ABCABC… s…ABCABC
p ABCABE… j=5; dj=2 p ABCABE…

SDA curs 9 I INFO 2015/2016 16


s…AAAAAAAAAA… s …AAAAAAAAA…
p AAAAAB j=5; dj=4 p AAAAAB…

s …ABCABD….. S …ABCABD…….
p ABCABC j=5; dj=0 P ABCABC

s…ABCDEF… s…ABCDEF…
p ABCDEA j=5; dj=-1 p ABCDEA

Precompilare
p d
A -1
AA -1-1
AAAAAB -1-1-1-1-14
ABCABC -100-100
ABCABCD -100-1003
ABCABD -100-102
MARGINE -1000000

SDA curs 9 I INFO 2015/2016 17


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 noteaza 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 a modelului
 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 INFO 2015/2016 18


Cautare Boyer-Moore

i=M;j=M;
while( j>0 && i<=N )
{
j=M;k=i;
while( j>0 && s[k-1]==p[j-1] )
{
k=k-1;
j=j-1;
}
if( j>0) i=i+d[s[k-1]];
}
poz=i-M;

SDA curs 9 I INFO 2015/2016 19

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