Algorytmy i struktury danych wy Nieznany (2)

background image

A

LGORYTMY

I

S

TRUKTURY

D

ANYCH

dr Edyta Łukasik

background image

P

ROBLEM

Dany jest wzorzec oraz tekst.

Należy wyszukać wszystkie wystąpienia wzorca w
podanym tekście.

1

2

3

4

5

6

7

8

9

10 11 12 13 14 15 16 17

A L I

B

A B A

A R

A B A B A

A L I

2

Wzorzec: ABA
Wystąpienia:

5, 10, 12

Tekst

background image

A

LGORYTM

NAIWNY

procedure Naiwny ( napis, wzor : String);
var
dw, dt, i, j : integer;
begin
dw := length (wzor);
dt := length (napis);
for i:=1 to dt-dw+1 do
begin
j:=0;
while (wzor[j+1]=napis[i+j]) and (j<dw) do j:=j+1;
if (j=dw) then writeln(’Wzorzec jest od pozycji’,i);
end;
end;

3

background image

A

LGORYTM

NAIWNY

-

WNIOSKI

Złożoność tego algorytmu:

wykonuje się dt*(dt-dw+1) porównań;

dw – dł. wzorca, dt – dł. tekstu;

zwykle dw<<dt więc koszt jest dt*dw.

Tak wysoka jego złożoność eliminuje go w

praktyce z przeszukiwania zbiorów binarnych.

Jedyną jego zaletą jest prostota, ale długi czas
działania bierze górę.

4

background image

A

LGORYTM

KMP

Idea tego algorytmu polega na zbadaniu wzorca,

w celu obliczenia ilości pozycji, o które należy
przesunąć wskaźnik, gdy stwierdzona zostanie
niezgodność wzorca i tekstu. Nie zawsze należy
badać wzorzec od początku. Może się zdarzyć, że
prefiks jest ten sam i tę informację trzeba umieć
wykorzystać.

Równolegle algorytm ten odkryli D. E. Knuth i
V. R. Pratt oraz J. H. Morris.

5

background image

A

LGORYTM

KMP –

TABLICA

PRZESUNIĘĆ

(1)

6

void tworzShiftKMP ( int dw, string wzor, int s[ ])
{ //w stringu elementy są od indeksu 0

int i, k;
s[0]=0; s[1]=0;
k=0;
for(i=2;i<=dw;i++)
{
while (k>0 && wzor[k]!=wzor[i-1]) k = s[k];
if (wzor[k] == wzor[i-1]) k++;
s[i] = k;
}

}

Wynikowa

tablica

background image

A

LGORYTM

KMP –

IMPLEMENTACJA

(2)

7

void KMP (int dw, int dn, string wzor, string napis)
{

int i, q;
int P[dn+1];
q=0; i=1;
tworzShiftKMP(dw, wzor, P);
while (i<=dn-dw+1)
{
while (q<dw && wzor[q]==napis[q+i-1]) q++;
if (q>=dw) cout<<"Wzorzec jest od pozycji "<<i<<endl;
if (q-P[q]>1) i+=q-P[q]; else i++;
q=P[q];
}

}

Długość wzorca

Długość napisu

background image

A

LGORYTM

KMP –

PRZYKŁAD

1

1.

Wzorzec: A B C D A B C

Tablica przesunięć dla wzorca:

[

0

,

0

,

0

,

0

,

0

,

1

,

2

,

3]

.

2.

Wzorzec: A B A B A B

Tablica przesunięć dla wzorca:

[

0

,

0

,

0

,

1

,

2

,

3

,

4]

.

3.

Wzorzec: A B C E A B C D A B C E

Tablica: przesunięć dla wzorca:

[

0

,

0

,

0

,

0

,

0

,

1

,

2

,

3

,

0

,

1

,

2

,

3

,

4]

.

8

background image

A

LGORYTM

KMP –

PRZYKŁAD

2

9

Wzorzec: ALARALA Tablica P = [0,0,0,1,0,1,2,3]

Tekst: MALARFALARALACA

i=1

M

ALARFALARALACA

q=0

A

LARALA

i:=i+1=2

i=2 M

ALAR

FALARALACA

q=P[0]=0

ALAR

ALA

q=1,...,4

i:=i+q-P[q]=2+4-0=6

background image

A

LGORYTM

KMP –

PRZYKŁAD

2

C

.

D

.

10

i=6 MALAR

F

ALARALACA

q=P[4]=0

A

LARALA

i:=i+1=7

i=7 MALARF

ALARALA

CA

q=P[0]=0

ALARALA

q=1,...,7

i:=i+q-P[q]=7+7-1=13

i=13: 13 > (15-7+1) więc już nie sprawdzamy!

background image

A

LGORYTM

KMP –

WNIOSKI

Algorytm ten działa w czasie proporcjonalnym do
dn+dw. Jest on rzędu O(dn+dw).

Największy zysk jest widoczny przy użyciu go dla
tekstów o wysokim stopniu samopowtarzalności.

Użycie jego jest wskazane w przeglądaniu
liniowym tekstu bez buforowania, gdyż nie cofamy
się po przeglądanym tekście.

Algorytm ten można znacznie zoptymalizować,
jeżeli często zdarza się szukanie tego samego
wzorca. Wtedy należy „wbudować” tablicę
przesunięć znanego wzorca.

11

background image

A

LGORYTM

B

OYERA

-M

OORE

A

W algorytmie tym porównywany jest ostatni znak
wzorca.

Jeżeli rozpatrywany znak nie występuje we
wzorcu, wówczas można przesunąć się o całą
długość wzorce do przodu.

Jeżeli występuje, wówczas przesuwamy się tak ze
wzorcem, aby te same znaki nałożyły się na siebie
i porównywanie jest kontynuowane.

Jest to algorytm badania niezgodności.

12

background image

13

void BM(int dw, int dn, string wzor, string napis)
{ int tabs[k+1], i, j, x,f;
tworzShiftBM(dw,wzor,tabs);
i=0;
while (i<=dn-dw+1)
{
j=dw;
while (napis[i+j]==wzor[j] && j>0) j--;
if (j<=0)
{cout<<"Wzorzec od pozycji "<<i<<endl; i++;}
else
{ x = tabs[index(napis[i+j])];
if (dw+1-j>x) i += dw+1-j;
else i += x;
}
}
}

A

LGORYTM

B

OYERA

-M

OORE

A

background image

A

LGORYTM

BM –

TABLICA

PRZESUNIĘĆ

14

Informuje ona o ile liter należy się przesunąć, licząc od końca

wzorca, aby trafić na właściwy znak.

void tworzShiftBM (int dw, string w, int ts[])
{
int i;
for(i=0;i<=k;i++) ts[i]=dw+1;
for(i=0;i<=dw;i++) ts[index(w[i])]=dw-i;
}

Funkcja indeks zwraca dla spacji 0 w pozostałych
przypadkach numer litery w alfabecie.

background image

A

LGORYTM

BM -

PRZYKŁAD

1

2

3

4

5

6

7

8

9

10

11 12

A

L

A

K

C

A

B

R

A

M

P

L

A

B

R

A

Znak A B C D E F G H I

J

K L Ł M N O P R

Index 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44

Tabs

0

2

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

1

A

B

R

A

15

M=4

,

x=4

i:=i+1

A

B

R

A

background image

A

LGORYTM

BM -

WNIOSKI

Algorytm ten jest najbardziej praktyczny, gdy

alfabet jest dostatecznie duży i wzorzec względnie
długi.

Koszt działania tego algorytmu wynosi O(dn),

gdzie dn jest długością przeglądanego tekstu.

Porównywanie symboli od strony prawej do lewej
jest bardzo efektywnym sposobem. W najlepszym

przypadku algorytm przegląda jedynie dn/dt część
całego tekstu.

16

background image

A

LGORYTM

K

ARPA

-R

ABINA

Wzorzec do wyszukania jest traktowany jako
klucz o długości M znaków, któremu przypisana
jest pewna wartość funkcji H(w). Obliczana jest
ona dla wzorca tylko raz.

Tekst jest analizowany po M kolejnych znaków.
Obliczana jest dla nich wartość funkcji H(t).

Te dwie wartości H(w) i H(t) są ze sobą
porównywane. Jeżeli są one równe, wtedy
sprawdzamy znak po znaku fragment tekstu i
wzorzec.

17

background image

A

LGORYTM

KR –

OBLICZANIE

KLUCZA

Każdy znak będziemy interpretować jako pewną
cyfrę dziesiętną. W przypadku ogólnym jako
cyfrę w systemie o podstawie d.

Wtedy H(w) możemy obliczyć z reguły Hornera
w czasie O(M).

Obliczenie H(t

s+1

) jest bardzo proste, jeżeli mamy

już obliczone H(t

s

): usuwamy z t

s

cyfrę

najbardziej znaczącą, przemnażamy wszystko
przez podstawę, aby przesunąć cyfry o jedną
pozycję w lewo i dodajemy cyfrę najmniej
znaczącą.

18

background image

A

LGORYTM

K

ARPA

-R

ABINA

(1)

19

Najpierw należy obliczyć hasz dla wzorca i hasz

dla pierwszych tylu znaków tekstu, ile wynosi

długość wzorca:

b= 10;
p= 33554393; //p – duża liczba pierwsza
hashW=0;
hashR=0;
for(i=1;i<=dlwzorca;i++)
{
hashW=(hashW*b+index(wzor[i])) % p;
hashR=(hashR*b+index(napis[i])) % p;
}

background image

A

LGORYTM

K

ARPA

-R

ABINA

(2)

20

bM1=1;
for(i=1;i<=dlwzorca-1;i++)

bM1 = (b*bM1) % p; //b do potęgi m-1

for(i=1;i<=dltekstu-dlwzorca+1;i++)
{
if (hashW==hashR)
{
j=0;
while (wzor[j+1]==napis[i+j] && j<dlwzorca) j++;
if (j==dlwzorca) cout<<"wzorzec od pozycji "<<i<<endl;
}
hashR=(hashR+b*p-index(napis[i])*bM1) % p;
hashR=(hashR*b+index(napis[i+m])) % p;
}

background image

A

LGORYTM

KR –

WNIOSKI

Jako podstawę systemu (nasze b) należy wybrać
wielokrotność

liczby

2.

Można

wtedy

zaimplementować operację mnożenia przez b jako
przesunięcie bitowe (np. dla b=64 o <<6 ).

Dla dużego p (liczba pierwsza) zmniejszamy
prawdopodobieństwo

wystąpienia

kolizji

spowodowanej niejednoznacznością funkcji H.

Koszt algorytmu O(M+N).

21

background image

A

LGORYTM

KR –

PRZYKŁAD

22

Alfabet składa się z liter: A, B, C, D. Za podstawę systemu
przyjmiemy

więc liczbę 4. Wartości liter wynoszą

odpowiednio: A-0, B-1, C-2, D-3. Za moduł przyjmiemy liczbę
pierwszą 23.

Szukany wzorzec to: BDA.

Tekst ma postać: CDBDACCAA.

Obliczamy hash wzorca:

H(W) = (1

4

2

+3

4

1

+0

4

0

) mod 23 = 28 mod 23 = 5

Obliczmy hash pierwszych trzech znaków tekstu:

H(T) = (2

4

2

+3

4

1

+1

4

0

) mod 23 = 45 mod 23 = 22

background image

A

LGORYTM

KR –

PRZYKŁAD

23

Jeżeli H(W)

H(T) (5

22), wtedy wzorzec na tej pozycji

na pewno nie wystąpił.

Sprawdzamy kolejną sekwencję znaków o długości 3

przesuwając się względem poprzedniej sekwencji o jeden znak:

C

DB

DB

D

H(T) = ( H(T) - (4

2

mod 23)

2) mod 23 = (22-16

2) mod 23 =

= -10 mod 23 = 13 – usunięcie najwyższej cyfry (

C

)

H(T) = H(T)

4 mod 23 = 13

4 mod 23 = 52 mod 23 = 6

– przesunięcie o rząd wielkości

H(T) = ( H(T) + 3 ) mod 23 = (6+3) mod 23 = 9

– dodanie ostatniej cyfry (

D

)

background image

A

LGORYTM

KR –

PRZYKŁAD

24

H(T) = 9

5 = H(W)

Więc to nie może być wzorzec, szukamy dalej!!!

Sprawdzamy kolejną sekwencję znaków o długości 3
przesuwając się względem poprzedniej sekwencji o jeden znak:

D

BD

BD

A

H(T) = ( H(T) - (4

2

mod 23)

3) mod 23 = (9-16

3) mod 23 =

= -39 mod 23 = 7 – usunięcie najwyższej cyfry (

D

)

H(T) = H(T)

4 mod 23 = 7

4 mod 23 = 5

– przesunięcie o rząd wielkości

H(T) = ( H(T) + 0 ) mod 23 = (5+0) mod 23 = 5

– dodanie ostatniej cyfry (

A

)

background image

A

LGORYTM

KR –

PRZYKŁAD

25

H(T) = 5 = H(W)

Mamy więc sekwencję podejrzaną o identyczną z

wzorcem. Teraz algorytmem naiwnym znak po znaku należy
przejrzeć tę sekwencję i wzorzec co do zgodności znaków.

Wzorzec: BDA

Sekwencja (fragment tekstu od pozycji 3): BDA.

Pierwsze wystąpienie wzorca zostało więc znalezione

w tekście. Występuje on w szukanym tekście i zaczyna się od
pozycji 3.


Wyszukiwarka

Podobne podstrony:
Algorytmy i struktury danych id Nieznany (2)
Algorytmy I Struktury Danych (W Nieznany (2)
Algorytmy i struktury danych Wykład 1 Reprezentacja informacji w komputerze
Algorytmy i struktury danych Wykład 3 i 4 Tablice, rekordy i zbiory
Algorytmy i struktury danych, AiSD C Lista04
Algorytmy i struktury danych 08 Algorytmy geometryczne
Instrukcja IEF Algorytmy i struktury danych lab2
Algorytmy, struktury danych i techniki programowania wydanie 3
Algorytmy i struktury danych 1
Ściaga sortowania, algorytmy i struktury danych
ukl 74xx, Informatyka PWr, Algorytmy i Struktury Danych, Architektura Systemów Komputerowych, Archit
cw 0 1, pwr, informatyka i zarządzanie, Informatyka, algorytmy i struktury danych
AIDS w7listy, studia, Semestr 2, Algorytmy i struktury danych AISD, AIDS
k balinska projektowanie algorytmow i struktur danych
W10seek, studia, Semestr 2, Algorytmy i struktury danych AISD, AIDS
ALS - 001-000 - Zadania - ZAJECIA, Informatyka - uczelnia, WWSI i WAT, wwsi, SEM II, Algorytmy i Str
kolokwium1sciaga, Studia Informatyka 2011, Semestr 2, Algorytmy i struktury danych

więcej podobnych podstron