Documente Academic
Documente Profesional
Documente Cultură
+
=
1
0
1
2
M
i
i b j
i
s stare
j
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
stare
j
= (stare
j
<< b) op T[a
j
]
Obs: Operatia nu trebuie sa produca transport pt. s
j
i
care sa afecteze s
j
i+1
Pentru b=1 op = sau logic
Definitii
Reprezint T tot ca un numar in baza 2
b
unde, x, o(cond) = 1 daca cond adevarata
= 0 in caz contrar
Exemplu
b=1, E = {a, b, c, d} p = ababc
T[a] = 11010 T[b] = 10101
T[c] = 01111 T[d] = 11111
starea initiala este 11111
T x x p
i
b i
i
M
[ ] ( ) = =
+
=
o
1
0
1
2
Exemplu
Sablon ababc
Sir a b d a b a b a b c
T[x] 11010 10101 11111 11010 10101 ..
Stare 11110 11101 11111 11110 11101 .
(11111)
stare
j-1
<< b | T[a
j
] = stare
j
Algoritmul deplaseaza-aduna
#define CUVANT 32
#define B 1
#define MAXSIM 128
In variabila lim vom calcula 2
B(M-1)
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);
Algoritmul deplaseaza-aduna - continuare
/* cautare */
matches=0; initial = ~0; first=p[0];
i=0;
while (i<N)
{
while(i<N && a[i]!=first) i++;
state=initial;
do
{
state=(state<<B) | T[a[i]];
if (state<lim)
matches++; /* identificare pe poz i-M+1 */
i++;
} while(state!=initial);
}
return matches;
}
Caracteristici
Este nevoie de b*M*|E| biti suplimentari de memorie si daca b*M s w,
atunci este nevoie de |E| cuvinte de memorie suplimentare.
Construirea tabelei T se face intr-un timp proportional cu:
Complexitatea cautarii, pentru cazul cel mai nefavorabil si pentru cazul
mediu este
unde
este timpul necesar calculului unui numar constant de operatii cu intregi de
M*b biti, folosind un cuvint de lungime w biti.
In practica (sabloane de 32 sa 64 biti), timpul mediu si cel mai nefavorabil
este O(N).
( ) O
M b
w
M
(
(
(
+
|
\
|
.
|
E
O
M b
w
N
(
(
(
|
\
|
.
|
M b
w
(
(
(
Extinderea algoritmului la identificarea
claselor de sabloane
x
*
- [x1x2xn] - clasa
- {x1} sau {x1x2xn} - complement
Extinderea algoritmului la identificarea
claselor de sabloane
Exemplu: = {a, b, c, d}.
Sablonul [Aa]b{b}*{bd} se potriveste peste
(sub)sirurile Abaca, abcda, dar nu si peste
abbac sau ababb.
Doua dimensiuni: lungimea M a sablonului si
dimensiunea descrierii sablonului, notata cu
M1.
Extinderea algoritmului la identificarea
claselor de sabloane
Exemplu: = {a, b, c, d}.
Sablonul este a{b}[ab]b{abc}.
M = 5 si M1 = 15.
T[a] = 11000 T[b] = 10011
T[c] = 11101 T[d] = 01101
T x x clasa
i
b i
i
M
[ ] ( ) = =
+
=
o
1
0
1
2
Algoritmul pt calculul lui T
valinit 111...111 (w biti)
for i = 1 to M do
if pi = * or pi este un complement
then valinit valinit & 1110
i
111
endfor
for i = 1 to |E| do
T[xi] valinit
endfor
for i = 1 to M do
foreach x e p
i
do
if p
i
este un complement
then T[x] T[x] | 0001
i
000
else T[x] T[x] & 1110
i
111
endforeach
endfor
5
2
Implementarea calculului lui T
void tinit(char *p)
{ unsigned int T[MAXSYM], initval, mask=1;
int i=0, M=0, M1=strlen(p);
/* calculeaza initval<-initval & 111..0i..111 */
initval=~0;
while(i<M1)
{ M++;
if(p[i]=='*')initval&=~mask;
else if(p[i]=='{'){initval&=~mask;
while(p[i]!=EOS &&
p[i]!='}') i++;}
else if(p[i]=='[')
while(p[i]!=EOS && p[i]!=']')i++;
mask<<=B;i++;
}
5
3
Implementarea calculului lui T - continuare
/* calculeza T[xi]<-initval pentru fiecare
xi din alfabet*/
for(i=0;i<MAXSYM;i++)T[i]=initval;
/* Actualizeaza T[x], cu x din sablon */
i=0; mask=1;
while(i<M1)
{ if(p[i]=='{') while(p[++i]!='}')
T[p[i]]|=mask;
else if(p[i]=='[')
while(p[++i]!=']') T[p[i]]&=~mask;
else T[p[i]]&=~mask;
i++; mask<<=B;
}
5
4
Identificarea cu max k nepotriviri
Fiecare stare individuala poate fi reprezentata printr-un
numar de maxim O(logM) biti.
- daca s
j
M
s k, am gasit o identificare cu maximum k
nepotriviri
- operatorul op este adunarea
- Deoarece ne intereseaza numai k nepotriviri, este
suficient sa alegem
b = sup|log
2
(k+1)| + 1
Problema transportului un bit de transport (overflow)
pt fiecare stare
5
5
Identificarea cu max k nepotriviri
- Obtinerea unei noi stari:
stare
j+1
=(stare
j
<< b) + T[x
j+1
]
- Conditia de identificare cu max k nepotriviri
s
j
M
+ overf
j
< (k+1) * 2
b(M-1)
Starea initiala se considera 00000, iar overflow-ul initial b+1 b+1b+1
Cazul
Sablonul ababc
Alfabetul {a, b, c, d}
T construit anterior
k = 2, b = 3 (b = sup|log
2
(k+1)| + 1)
5
6
Exemplu
Sablonul ababc
Alfabetul {a, b, c, d}
T construit anterior
k = 2, b = 3
starea initiala 00000
overflow initial 44444
sir a b d a b
T[x] 11010 10101 11111 11010 10101
stare 11010 20201 13121 02220 32301
overf 44440 44400 44000 40000 00000
sir a b a b c
T[x] 11010 10101 11010 10101 01111
stare 30020 10301 10020 10301 00121
overf 04000 40000 04000 40000 04000
57
Algoritmul pentru max k nepotriviri
mask 1
Mb
001
2b
001
b
00
lim (k+1) << (M-1)*b
stare 0 overf mask
for i = 1 to N do
stare (stare << b) + T[a
i
]
overf (overf << b) | (stare & mask)
stare stare & ~mask
if (stare+overf) < lim
then identificare la pozitia i-M+1
endfor
58