Documente Academic
Documente Profesional
Documente Cultură
Capitole curs
Informatii curs
Pagina Web a cursului
http://turing.cs.pub.ro/sptr_07
Cursul se afla si pe curs.cs.pub.ro
Notare
Laborator 30%
Tema de casa de semestru 20%
Examen
50%
Minimum 6 prezente la laborator
Curs Nr. 1
Prelucrarea sirurilor de caractere
Algoritmi de identificare a
sirurilor de caractere
Introducere
Algoritmul cautarii directe
Algoritmul Knuth-Morris-Prat
Algoritmul Boyer-Moore
Algoritmul Rabin-Karp
Algoritmul deplaseaza-aduna
1 Introducere
Identificarea (recunoasterea) sabloanelor in siruri de
caractere
sir a, lungime N
sablon p, lungime M
Introducere
Prima aparitie / toate aparitiile
Cum difera cautarea in sir a unui sablon de cautarea unei chei
1. Algoritmul cautarii directe: Cazul cel mai nefavorabil timp
proportional cu N*M; in multe cazuri practice, timpule mediu este
proportional cu N+M.
2. 1970 - S.A. Cook a demonstrat teoretic ca exista un algoritm de
identificare a sabloanelor cu timpul cel mai nefavorabil
proportional cu N+M. D.E. Knuth, J.H. Morris si V.R. Pratt au
construit un astfel de algoritm.
3. 1976 - R.S. Boyer si J.S. Moore au descoperit un algoritm chiar
mai rapid decat (2) in multe aplicatii, deoarece examineaza in
multe cazuri numai o parte din caracterele textului.
4. 1980 - R.M. Karp si M.O. Rabin au observat ca problema
identificarii sabloanelor nu este mult diferita de o problema
standard de cautare si au descoperit un algoritm care are virtual
timpul proportional cu M+N.
3. Algoritmul Knuth-Morris-Pratt
Idee
startul fals al identificarii consta din caractere
deja cunoscute
a sir, i index in sir, N
p sablon, j index in sablon, M
Caz particular: primul caracter din sablon nu mai apare in
sablon
i
sir:
1000001000000
a
sablon:
1000000
p
j
nu i = i j + 1
da nu se modifica i si j = 0
Caz general
sir:
1010100111
sablon:
10100111
j=4
Caz general
Trebuie cautat k maxim cu aceasta proprietate.
Daca nu exista k cu ac. proprietatea atunci cautarea se
reia de la pozitia i si j=0.
Daca exista un astfel de k atunci
i = i k, j = 0 .
Se calculeaza valorile unui vector next[j] pt pj p
(cu M elemente)
= cu cat trebuie decrementat i la aparitia unei
nepotriviri pe pozitia j
next[j] = numarul maxim de caratere nr de la inceputul
sablonului care identifica cu ultimele nr caractere din
sablon pana la pozitia j-1 = kmax cu proprietatea anterioara
Vectorul next
10100111
j=4
next[4] = 2
Reluare cautare i = i next[j], j = 0
next[j]
1
6
7
1
1
0 potriviri
0 potriviri
1 potrivire
2 potriviri
0 potriviri
1 potrivire
1 potrivire
Vectorul next
Caracterele identice definesc urmatorul loc posibil in care
sablonul se poate identifica cu sirul, dupa ce se gaseste o
nepotrivire pe pozitia j (caracterul p[j]).
Distanta cu care trebuie sa ne intoarcem in sir este exact
next[j], adica numarul de caractere care coincid.
Este convenabil next[0] = -1.
Exemplu
i=4
ar trebui i = 2 si j = 0
sir:
1010100111 a
sablon: 10100111
p
j=4
next[4] = 2
acelasi efect daca i nemodificat si j = 2
sir:
1010100111 a
sablon:
10100111 p
Algoritmul Knuth-Morris-Pratt
int cautKMP(char *p, char *a)
{ int i, j;
int M=strlen(p);
int N=strlen(a);
initnext(p);
for (i=0, j=0; j<M && i<N; i++, j++)
while ((j>=0) && (a[i] != p[j]))
j = next[j];
if (j==M)
return i-M;
else
return i;
}
Obs: Pt. j = 0 si a[i] != p[0] este necesar ca i+, j = 0 deci next[0] = -1
s0
s1
s2
s3
s4
s5
s6
s7
sf
goto
goto
goto
goto
goto
goto
goto
goto
sm;
s0;
s0;
s1;
s2;
s0;
s1;
s1;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
Caracteristici KMP
4 Algoritmul Boyer-Moore
Potrivit daca intoarcerea in text nu este dificila
UN EXEMPLU DE CAUTARE RAPIDA
UTARE
UTARE
UTARE
UTARE
UTARE
Algoritmul Boyer-Moore
Vectorul skip se defineste pentru fiecare caracter
din alfabet
arata, pentru fiecare caracter din alfabet, cat de mult
se sare (se deplaseaza sablonul la dreapta) in sir daca
acest caracter a provocat nepotrivirea
rutina initskip initializeaza skip:
skip[index(p[j])] = M-j-1, j=0,M-1
pentru caracterele din sablon
skip[index(c)] = M pentru restul de caractere
din alfabet
Algoritmul Boyer-Moore
int caut_BM(char *p, char*a)
{ int i, j, t;
int M=strlen(p), N = strlen(a);
initskip(p);
for (i=M-1, j=M-1; j>=0; i--, j--)
while (a[i]!=p[j])
{ t = skip[index(a[i])];
i+ = (M-j > t) ? M-j : t;
if (i >= N) return N;
j = M-1;
return i+1;
}
Algoritmul Boyer-Moore
Combinarea a doua metode pentru a afla exact cu
cat trebuie deplasat la dreapta sirul: metoda
prezentata si metoda vectorului next din algoritmul
Knuth-Morris-Prat, in varianta de la dreapta la
stinga, pentru ca apoi sa se aleaga in skip cea mai
mare valoare.
In conditiile acestei modificari, este valabila
urmatoarea proprietate.
Proprietate: Algoritmul Boyer-Moore face cel
mult M+N comparatii de caractere si foloseste N/M
pasi, daca alfabetul nu este mic si sablonul este
scurt.
5. Algoritmul Rabin-Karp
Idee
Considera textul ca fiind o memorie mare si
trateaza fiecare secventa de M caractere a textului
ca o cheie intr-o tabela de dispersie (hash).
Trebuie sa calculam functia de dispersie pentru
toate secventele posibile de M caractere
consecutive din text si sa verificam daca valorile
obtinute sunt egale cu functia de dispersie a
sablonului.
Artificiu pt. a nu tine toata tabela de dispersie in
memorie.
Algoritmul Rabin-Karp
int caut_RK(char *p, char *a)
{
int i;
long int dM=1, h1=0, h2=0;
int M=strlen(p), N=strlen(a);
for (i=1; i<M; i++) dM = (d*dM) % q;
// calculeaza d(M-1)mod q in dM
for (i=0; i<M; i++)
yi+1 mod q = ( yi * d + a[i+1]) mod q
{h1 = (h1*d + index(p[i]))%q;
// functia hash pt sablon
h2 = (h2*d + index(a[i]))%q;
// functia hash pt text
}
for (i=0; h1!=h2; i++)
{h2 = (h2 + d*q - index(a[i])*dM)%q;
// d*q se adauga pt a mentine expresia >0
h2 = (h2 * d + index(a[i+M]))%q;
if (i > (N-M)) return N;
}
y1 mod q = ( (y a[i] * dM-1) mod q * d + a[i+M]) mod q
return i;
Caracteristici RK
6. Algoritmul deplaseaza-aduna
Idee
Algoritmul reprezinta starea cautarii ca un
numar, si fiecare pas in cautare
(identificare) este descris printr-un numar
de operatii aritmetice si logice
Acest lucru este posibil daca numerele
folosite sunt suficient de mari pentru a
putea reprezenta toate starile posibile in
cursul rularii
Algoritmul deplaseaza-aduna
Se poate generaliza usor la urmatoarele cazuri:
1. Dont care symbols, deci identificarea cu orice
caracter pe o pozitie
2. Identificarea cu un caracter dintr-o clasa de
caractere (un interval)
3. Identificarea cu un caracter din complementul
unei clase.
4. Identificarea cu un numar dat K de nepotriviri
5. Identificarea mai multor sabloane in paralel.
Ipoteze
a
p
i
j
Ipoteze
starei - p[1]p[i] ? a[j-i+1] a[j]
{sji}, i=1,M multime de stari dupa citirea
caracterului j din sir
sji = numarul de nepotriviri intre
p[1]p[i] si a[j-i+1] a[j]
Apare identificare daca sjM = 0
Exemplu
sji-1
a babc
ab abc
aba bc
abab c
ababc
cbbabab abcaba
j-1
Exemplu
i
sj-1i
a babc
ab abc
aba bc
abab c
ababc
cbbababa bcaba
j
Ti[a]
sji
Exemplu
i
sj-1i
a babc
ab abc
aba bc
abab c
ababc
cbbababa bcaba
j
Ti[a]
sji
Definitii
Se defineste T[x] pentru x
Ti[x]
= 0 daca pi = x, i=1,M
= 1 in caz contrar
(prin compararea fiecarui caracter x din alfabet cu
p[0]p[M])
Se observa relatia
sji = sj-1i-1 + Ti[aj] i=1,M
Identificarea apare daca sjM = 0
Cuvant w
b biti necesari pentru a reprezenta o stare
Definitii
Vector de stari reprezentat ca un numar in
baza 2b
M 1
stare
s 2
i 0
j
i 1
bi
Definitii
Actualizare la citirea unui nou caracter:
deplasez vect. de stari cu b pozitii la stanga = avans
cu 1 pozitie in text
actualizez starile pe baza lui T si fac o operatie
potrivita
Definitii
Reprezint T tot ca un numar in baza 2b
T [x ]
M 1
( x p
i0
unde,
x, (cond)
bi
)
2
i 1
Exemplu
b=1, = {a, b, c, d} p = ababc
T[a] = 11010
T[b] = 10101
T[c] = 01111
T[d] = 11111
starea initiala este 11111
Exemplu
Sablon
Sir
T[x]
Stare
(11111)
ababc
a
b
d
a
b
a b a b
11010 10101 11111 11010 10101 ..
11110 11101 11111 11110 11101 .
starej-1 << b
| T[aj] = starej
Algoritmul deplaseaza-aduna
#define
#define
#define
CUVANT
B
MAXSIM
32
1
128
Algoritmul deplaseaza-aduna
int caut_shadd(char *p,char *a)
{unsigned int state, lim, first, initial;
unsigned int T[MAXSIM];
int i, j, matches, M=strlen(p), N=strlen(a);
if(M>CUVINT)
{printf("\n Error: Utilizati dim. sablon<dim.
cuvint\n");
return -1;
}
/* preprocesare */
for(i=0; i<MAXSIM; i++) T[i]=~0;
lim=0;
for(i=0,j=1; i<M; i++,j<<=B)
{
T[p[i]] &= ~j;
lim |= j;
}
lim = ~(lim>>B);
Caracteristici
M b
M
O
M b
O
N
M b
unde w
x
*
[x1x2xn] - clasa
{x1} sau {x1x2xn} - complement
M 1
(x clasa
i0
i 1
) 2
bi
Cazul
Sablonul ababc
Alfabetul {a, b, c, d}
T construit anterior
k = 2, b = 3
(b = sup|log2(k+1)| + 1)
Exemplu
sir
T[x]
stare
overf
a
11010
11010
44440
sir
T[x]
stare
overf
b
10101
20201
44400
d
11111
13121
44000
a
11010
30020
04000
Sablonul ababc
Alfabetul {a, b, c, d}
T construit anterior
k = 2, b = 3
starea initiala 00000
overflow initial 44444
a
11010
02220
40000
b
10101
10301
40000
b
10101
32301
00000
a
11010
10020
04000
b
10101
10301
40000
c
01111
00121
04000
57
58