Temat: Algorytmy wyszukiwania wzorca w tekście

Podobne dokumenty
Wykład 6. Wyszukiwanie wzorca w tekście

1 abbbaabaaabaa -wzorzec: aaba

Algorytmy przeszukiwania wzorca

Algorytmy i struktury danych. wykład 8

Wstęp do Programowania potok funkcyjny

Analiza algorytmów zadania podstawowe

Algorytmy i struktury danych. Drzewa: BST, kopce. Letnie Warsztaty Matematyczno-Informatyczne

Zadanie 1 Przygotuj algorytm programu - sortowanie przez wstawianie.

Jeśli czas działania algorytmu zależy nie tylko od rozmiaru danych wejściowych i przyjmuje różne wartości dla różnych danych o tym samym rozmiarze,

Zadanie 1. Zmiana systemów. Zadanie 2. Szyfr Cezara. Zadanie 3. Czy liczba jest doskonała. Zadanie 4. Rozkład liczby na czynniki pierwsze Zadanie 5.

Kody Tunstalla. Kodowanie arytmetyczne

Wstęp do Informatyki zadania ze złożoności obliczeniowej z rozwiązaniami

Algorytmy w teorii liczb

Zadania do wykonania. Rozwiązując poniższe zadania użyj pętlę for.

Dr inż. Robert Wójcik, p. 313, C-3, tel Katedra Informatyki Technicznej (K-9) Wydział Elektroniki (W-4) Politechnika Wrocławska

Indukcja. Materiały pomocnicze do wykładu. wykładowca: dr Magdalena Kacprzak

Zaawansowane algorytmy i struktury danych

Temat: Algorytm kompresji plików metodą Huffmana

Odwrotna Notacja Polska

Strategia "dziel i zwyciężaj"

Wstęp do informatyki- wykład 1

Algorytmy tekstowe. Andrzej Jastrz bski. Akademia ETI

Zasada indukcji matematycznej

Nierówność Krafta-McMillana, Kodowanie Huffmana

1. Wykład NWD, NWW i algorytm Euklidesa.

1 Podstawy c++ w pigułce.

0 + 0 = 0, = 1, = 1, = 0.

Zadanie 1. Potęgi (14 pkt)

Kodowanie i kompresja Streszczenie Studia dzienne Wykład 9,

Struktury danych i złożoność obliczeniowa Wykład 2. Prof. dr hab. inż. Jan Magott

TEORETYCZNE PODSTAWY INFORMATYKI

Zaawansowane algorytmy i struktury danych

Wykład 4. Określimy teraz pewną ważną klasę pierścieni.

wagi cyfry pozycje

Podstawy Informatyki. Sprawność algorytmów

Algorytmy tekstowe na przykładzie KMP

Matematyka dyskretna. Andrzej Łachwa, UJ, /14

Algorytm selekcji Hoare a. Łukasz Miemus

LABORATORIUM 3 ALGORYTMY OBLICZENIOWE W ELEKTRONICE I TELEKOMUNIKACJI. Wprowadzenie do środowiska Matlab

Język ludzki kod maszynowy

Algorytmy i Struktury Danych.

Podstawy programowania w języku C i C++

Programowanie Równoległe i Rozproszone. Algorytm Kung a. Algorytm Kung a. Programowanie Równoległe i Rozproszone Wykład 8. Przygotował: Lucjan Stapp

Wykład 6. Metoda eliminacji Gaussa: Eliminacja z wyborem częściowym Eliminacja z wyborem pełnym

struktury danych dla operacji słownikowych

Wstęp do programowania

METODY KOMPUTEROWE W OBLICZENIACH INŻYNIERSKICH

Wstęp do informatyki- wykład 1 Systemy liczbowe

Złożoność informacyjna Kołmogorowa. Paweł Parys

Analiza algorytmów zadania podstawowe

teoria informacji Entropia, informacja, kodowanie Mariusz Różycki 24 sierpnia 2015

Definicja. Ciąg wejściowy: Funkcja uporządkowująca: Sortowanie polega na: a 1, a 2,, a n-1, a n. f(a 1 ) f(a 2 ) f(a n )

Języki i operacje na językach. Teoria automatów i języków formalnych. Definicja języka

mgr inż. Grzegorz Kraszewski SYSTEMY MULTIMEDIALNE wykład 4, strona 1. GOLOMBA I RICE'A

Treść wykładu. Pierścienie wielomianów. Dzielenie wielomianów i algorytm Euklidesa Pierścienie ilorazowe wielomianów

Kompresja bezstratna. Entropia. Kod Huffmana

Rekurencja, schemat rekursji i funkcje pierwotnie rekurencyjne

Obliczenia iteracyjne

Matematyka dyskretna. Andrzej Łachwa, UJ, /15

ALGORYTMY Algorytm poprawny jednoznaczny szczegółowy uniwersalny skończoność efektywność (sprawność) zmiennych liniowy warunkowy iteracyjny

Rachunek prawdopodobieństwa

Podstawy Programowania C++

ARYTMETYKA BINARNA. Dziesiątkowy system pozycyjny nie jest jedynym sposobem kodowania liczb z jakim mamy na co dzień do czynienia.

ZŁOŻONOŚĆ OBLICZENIOWA ALGORYTMÓW

WHILE (wyrażenie) instrukcja;

Luty 2001 Algorytmy (7) 2000/2001

Tablice z haszowaniem

operacje porównania, a jeśli jest to konieczne ze względu na złe uporządkowanie porównywanych liczb zmieniamy ich kolejność, czyli przestawiamy je.

WHILE (wyrażenie) instrukcja;

Języki programowania zasady ich tworzenia

Wykład 5. Sortowanie w czasie liniowologarytmicznym

Macierze. Rozdział Działania na macierzach

Matematyka dyskretna. Andrzej Łachwa, UJ, /14

Kodowanie informacji

Metody probabilistyczne

Efektywność Procedur Obliczeniowych. wykład 5

INŻYNIERIA BEZPIECZEŃSTWA LABORATORIUM NR 2 ALGORYTM XOR ŁAMANIE ALGORYTMU XOR

Symulacja w przedsiębiorstwie

Sortowanie topologiczne skierowanych grafów acyklicznych

Prawdopodobieństwo geometryczne

Zasady analizy algorytmów

Projekt AS KOMPETENCJI jest współfinansowany przez Unię Europejską w ramach środków Europejskiego Funduszu Społecznego

Wybrane zagadnienia teorii liczb

Matematyka dyskretna. Andrzej Łachwa, UJ, /10

ZADANIE 1. Ważenie (14 pkt)

EGZAMIN MATURALNY Z INFORMATYKI 17 MAJA 2016 POZIOM PODSTAWOWY. Godzina rozpoczęcia: 14:00 CZĘŚĆ I WYBRANE: Czas pracy: 75 minut

Kod znak-moduł. Wartość liczby wynosi. Reprezentacja liczb w kodzie ZM w 8-bitowym formacie:

Podstawowe algorytmy i ich implementacje w C. Wykład 9

Tablice z haszowaniem

Konstrukcje warunkowe Pętle

Algorytmy i struktury danych. Wykład 4

Luty 2001 Algorytmy (4) 2000/2001

Jednym z najprostszych sposobów porządkowania jest technika stosowana przy sortowaniu listów:

wstęp do informatyki i programowania część testowa (25 pyt. / 60 min.)

Samodzielnie wykonaj następujące operacje: 13 / 2 = 30 / 5 = 73 / 15 = 15 / 23 = 13 % 2 = 30 % 5 = 73 % 15 = 15 % 23 =

Wstęp do programowania

Podstawy Informatyki Maszyna Turinga

Maszyna Turinga. Algorytm. czy program???? Problem Hilberta: Przykłady algorytmów. Cechy algorytmu: Pojęcie algorytmu

Wprowadzenie do informatyki i użytkowania komputerów. Kodowanie informacji System komputerowy

Wskaźniki. Programowanie Proceduralne 1

Transkrypt:

Temat: Algorytmy wyszukiwania wzorca w tekście 1. Sformułowanie problemu Dany jest tekst T oraz wzorzec P, będące ciągami znaków o długości równej odpowiednio n i m (n m 1), nad pewnym ustalonym i skończonym alfabetem. Należy znaleźć wszystkie wystąpienia wzorca P w tekście T. Będziemy zakładać, że zarówno tekst jak i wzorzec są ciągami znaków zapamiętanymi w strukturze danych o dostępie indeksowym (np. w tablicach: char T[n], P[m]) Przykład T = aabbcadbbbacadbdcbbacadba P = cad Wystąpienia wzorca P w tekście T podamy wskazując pozycje s w teście, dla których: T[s] = P[0] i T[s+1] = P[1] i... i T[s+m-1]=P[m-1]. W przykładzie s = 4, s = 11, s = 20. Gdy T = alalalala P = ala to wystąpienia wzorca P w tekście T są następujące: s = 0, s = 2, s = 4, s = 6. 1

2. Notacja i terminologia * - zbiór wszystkich tekstów (słów) utworzonych z symboli alfabetu ε - słowo o długości zero nazywane słowem pustym x - długość słowa x xy - konkatenacja (złożenie) słów x i y w x w jest prefiksem (przedrostkiem ) słowa x, gdy x = wy dla pewnego słowa y * w x w jest sufiksem (przyrostkiem ) słowa x, gdy x = yw dla pewnego słowa y * X[s... k] fragment tekstu X od znaku o indeksie s do znaku o indeksie k X k k - znakowy prefiks tekstu X. Jeżeli X = X[0... t], to X k =X[0.. k-1] Gdy T[s... s+m-1] = P[0... m-1] dla 0 s n m, to mówimy, że wzorzec P występuje z przesunięciem s w tekście T albo równoważnie, że wzorzec P występuje w tekście T od pozycji s. Jeżeli P występuje w tekście T z przesunięciem s, to s nazywamy poprawnym przesunięciem, w przeciwnym razie s nazywamy niepoprawnym przesunięciem. 2

Przykład ab abcca cca abcca słowo ab jest prefiksem słowa abcca słowa cca jest sufiksem słowa abcca Jeżeli X = abcabcd, to X[2... 5] = cabc oraz X 3 = abc T = ababcdabc P = bcd Przesunięcie s=0 jest niepoprawnym przesunięciem wzorca P względem tekstu T, natomiast przesunięcie s = 3 jest poprawnym przesunięciem wzorca P względem tekstu T. 3. Algorytm naiwny Idea tego algorytmu polega na przeglądaniu tekstu T sekwencyjnie, kolejno przesuwając się po jednym znaku tekstu od lewej do prawej i sprawdzaniu za każdym razem, czy kolejne znaki wzorca P pokrywają się z kolejnymi znakami tekstu. Algorytm naiwny s = 0; while (s <= n-m) j =0; while (j < m) if (P[j]= =T[s+j]) j = j+1; else break; if (j == m) P występuje w T od pozycji s ; s++; 3

Przykład n=18, m=4 T: aaabaababbababaaba P: baba P: baba P: baba P: baba... P: baba P występuje w T od pozycji 9... P: baba P występuje w T od pozycji 11... P: baba Koszt czasowy algorytmu naiwnego Operacją elementarną są porównania między znakami wzorca i tekstu. Jeśli wzorzec nie występuje w tekście i przekonujemy się o tym po pierwszym porównaniu (przy każdym położeniu wzorca względem tekstu), to wykonujemy minimalną liczbę porównań równą n-m+1. Jeżeli wzorzec występuje na każdej pozycji tekstu, na przykład, gdy: T: a n, P: a m, to wykonujemy maksymalną liczbę porównań równą : (n - m+1) m. Zatem: ( n, m) = Θ( ( n m ) m) T 1 max + 4

4. Algorytm Knutha - Morrisa - Pratta (KMP) Algorytm KMP opiera się na wykorzystaniu pomocniczej funkcji Π (zwanej funkcją prefiksową), którą wyznacza się dla wzorca, niezależnie od tekstu. Algorytm wyznaczający funkcję prefiksową ma złożoność liniową względem długości wzorca. Funkcja ta pozwala na zwiększenie (ale tylko w określonych sytuacjach) przesunięcia wzorca względem tekstu. W algorytmie naiwnym przesunięcie zwiększa się zawsze tylko o jeden. Π : 1,..., m 0,1,..., m Π[q] = "maksymalna długość prefiksu wzorca P, który jest równocześnie sufiksem P q " Π[q]= max k : k < q, P k P q Wiedząc, że q znaków wzorca pasuje przy przesunięciu o s, następne potencjalnie poprawne przesunięcie s' można wyliczyć jako: s' = s+ q - Π[q] W najlepszym przypadku s' = s+q (gdy Π[q]=0) i eliminujemy wówczas przesunięcia: s+1, s+2,..., s+q-1. 5

Przykład P: Π[1] = 0 P: Π[2] = 0 P: Π[3] = 1 P: Π[4] = 2 P: Π[5] = 3 6

P: Π[6] = 0 P: Π[7] = 1 T : abacbababaabcbab... P : q 1 2 3 4 5 6 7 Π[q] 0 0 1 2 3 0 1... a b a c b a b a b a a b c b a b... przesu- a b a b a c a nięcie a b a b a c a s s' s' = s+ q - Π[q] s' = 5+ 5-3 = 7 7

Po przesunięciu wzorca o 5 pozycji w prawo, 5 kolejnych znaków wzorca pokrywa się ze znakami tekstu. Znając te 5 znaków wzorca wiemy, że przesunięcie o tylko jedno miejsce w prawo nie jest poprawne, gdyż a wypadnie pod literą b. Natomiast przesunięcie o dwa miejsca w prawo ma szansę powodzenia. Informacje tego typu mogą być wydedukowane na podstawie samego wzorca. Algorytm obliczania funkcji prefiksowej Π Π[1] =0; k=0; for (q = 2; q<=m; q++) while (k>0 && P[k]!=P[q-1]) k = Π [k]; if (P[k] = =P[q-1]) k = k+1; Π [q] = k; Algorytm KMP q= 0; for ( i =0; i < n; i++) while (q>0 && P[q]!=T[i]) q = Π [q]; if (P[q] = = T[i]) q= q+1; if (q = = m) "wzorzec znaleziono na pozycji ; q = Π [q]; 8

Koszt czasowy algorytmu KMP Koszt obliczenia wszystkich wartości funkcji Π wynosi O(m), gdyż : (1) warunek P[k] =P[q-1] (po pętli) może być sprawdzany co najwyżej m razy, a z drugiej strony, (2) warunek P[k]!=P[q] (w pętli) też może być sprawdzany co najwyżej m razy. Stąd, razem mamy co najwyżej 2m porównań. Analogicznie można uzasadnić, że koszt zasadniczego algorytmu KMP jest równy O(n). Można pokazać, że całkowity koszt algorytmu KMP wynosi O(n+m). Jest to właściwie koszt średni, ale przypadek pesymistyczny dla algorytmu KMP zdarza się bardzo rzadko. Tym przypadkiem jest sytuacja, w której wzorzec P=a m oraz tekst T=a n. Wówczas przesunięcie w każdym kroku pętli (*) zwiększa się tylko o jeden. 9

5. Algorytm Rabina-Karpa (RK) Metodę zastosowaną w tym algorytmie można nazwać metodą ''odcisku''. Zamiast porównywać znak po znaku wzorzec z tekstem, używa się specjalnej funkcji (właśnie "odcisku ), która wiąże z każdym ciągiem znaków o długości m jedną liczbę. Liczba ta ma identyfikować blok o m znakach. Zamiast porównywać ciągi znaków, porównuje się reprezentujące je liczby (odciski). Ogólnie można przyjąć, że każdy znak jest cyfrą w systemie pozycyjnym o podstawie d, gdzie d=card(σ). Zatem każdy ciąg m kolejnych znaków można rozumieć jako liczbę m cyfrową w systemie pozycyjnym o podstawie d. Niech p oznacza liczbę odpowiadającą wzorcowi P, a t s oznacza liczbę odpowiadającą ciągowi znaków T[s... s+m-1]. Prawdziwa jest następująca własność: p = t s wtedy i tylko wtedy, gdy T[s... s+m-1] =P[0... m-1], czyli wzorzec P występuje w tekście T od pozycji s. Liczba p jest wartością wielomianu: W x = P m 1 + P m 2 x + P m 3 p dla x=d. 2 m 1 ( ) [ ] [ ] [ ] x +... + P[ 0] x Liczba t s jest wartością wielomianu: x = T s + m 1 + T s + m 2 x + T Wt s 2 m 1 ( ) [ ] [ ] [ s + m 3] x +... + T[ s] x dla x=d. 10

Wartości p i t 0 możemy policzyć kosztem liniowym stosując schemat Hornera : W ( x) = a0 + x( a1 + x( a2 +... + x( a n 1 + xan ))...) Łatwo zauważyć, że wartości t s dla s=1, 2,..., n-m można obliczyć kosztem stałym, ze wzoru: t s =d (t s-1 -d m-1 T[s])+T[s+m] Algorytm Rabina-Karpa s = 0; p = W p (d); // d = card(σ) t 0 = W t0 (d); if ( p = = t 0 ) wzorzec P występuje w tekście T z przesunięciem s=0 ; while (s<=n-m) t s =d (t s-1 -d m-1 T[s])+T[s+m]; s++; if ( p = = t s ) wzorzec P występuje w tekście T z przesunięciem s ; Przykład Σ=0, 1, 2, 3, 4, 5, 6, 7, 8, 9, d=10 T: 34587656743256989 P:56983 Wówczas: t 0 = 34587, t 1 =10 (34 587-10 4 3)+6=45876 t 2 =58765, t 3 = 87656 itd. 11

Koszt czasowy algorytmu RK Operacją elementarną nie są tym razem porównania między znakami wzorca i tekstu, a operacje arytmetyczne realizowane przy obliczaniu odcisku wzorca i tekstu. Odcisk wzorca można policzyć kosztem O(m). Odcisk t 0 również można obliczyć takim samym kosztem. Odciski t 1,...,t n-m można policzyć stałym kosztem, gdy mamy wcześniej policzoną jednorazowo wartość d m-1 (można tę wartość policzyć kosztem O(logm), stosując algorytm oparty na metodzie "dziel i zwyciężaj". Zatem koszt całego algorytmu wyniesie O(n+m). W związku z tym, że alfabet wzorca i tekstu może być duży (np. d = card(σ)=256) pojawiają się dwa problemy związane z implementacją algorytmu RK. Problem 1 Wartości p i t 0, t 1,..., t n-m mogą być bardzo duże, a wtedy nie można zakładać, że każda operacja arytmetyczna ma ten sam koszt co operacja arytmetyczna dla liczb mieszczących się w słowie maszynowym. Rozwiązanie Problemu 1 Problem ten można rozwiązać stosując zamiast zwykłej arytmetyki, arytmetykę modulo, tzn. obliczone wartość odcisku dzieli się modulo pewna wybrana liczba pierwsza q. Zwykle wybiera się q takie, że d q powinno być nie większe niż jedno słowo maszynowe. Przy tym założeniu w trakcie obliczania wartości odcisków będą używane standardowe operatory arytmetyczne (tj. dla małych liczb ). 12

Algorytm Rabina-Karpa w arytmetyce modularnej s = 0; p = W p (d) % q; t 0 = W t0 (d) % q if ( p = = t 0 ) wzorzec P występuje w tekście T z przesunięciem s=0 ; while (s<=n-m) t s =(d (t s-1 -d m-1 T[s])+T[s+m]) % q; s++; if ( p = = t s ) wzorzec P występuje w tekście T z przesunięciem s ; Problem 2 Pojawia się jednak problem niejednoznaczności, ponieważ prawdziwość warunku p = = t s nie oznacza, że na pewno P[0...m-1]=T[s... s+m-1]. Równość reszt z dzielenia dwóch liczb nie oznacza bowiem, że same liczby są na pewno sobie równe. Aby algorytm nie zwracał niepoprawnych wyników należy zatem, w każdym przypadku, gdy p = = t s dodatkowo sprawdzić równość odpowiednich ciągów badając je znak po znaku. Powoduje to jednak, że koszt algorytmu RK, w najgorszym przypadku wynosi Θ((n-m+1) m). Przykładem przypadku pesymistycznego dla algorytmu RK jest przypadek: T = a n i P = a m. Wówczas każdy blok tekstu o długości m daje ten sam odcisk równy odciskowi wzorca i konieczne jest sprawdzenie znak po znaku. 13

W bardzo wielu zastosowaniach, zajście zdarzenia p== t s przy jednoczesnej niezgodności wzorca z tekstem, jest bardzo rzadkie. Liczbę q można tak wybrać, aby prawdopodobieństwo takiego zdarzenia było równe 1/n. Przy dużym n prawdopodobieństwo pomyłki jest zatem bardzo małe i można nie sprawdzać zgodności znak po znaku, co poowduje, że czas oczekiwany (złożoność średnia) wykonania algorytmu RK wynosi O(n+m). Wersja bez sprawdzania symbol po symbolu i z arytmetyką modulo q gwarantuje liniowy czas wykonania, ale z małym prawdopodobieństwem wynik może się okazać niepoprawny. Takie algorytmy, które z dopuszczalnym prawdopodobieństwem zwracają wynik niepoprawny nazywamy algorytmami Monte Carlo (zawsze szybko i prawdopodobnie poprawnie). Wersja algorytmu ze sprawdzaniem w przypadku, gdy odcisk wzorca jest zgodny modulo q z odciskiem bloku tekstu gwarantuje poprawny wynik, ale z małym prawdopodobieństwem algorytm ten będzie działał dłużej niż liniowo. Algorytmy tego typu nazywane są algorytmami Las Vegas (zawsze poprawnie i prawdopodobnie szybko). Problem 3 Wartości W p (d) oraz W t0 (d) to nadal duże liczby, dla dużego d, pomimo tego, że wartości t 0 oraz p są mniejsze równe q. Jak zatem obliczyć t 0 oraz p, aby nie używać arytmetyki dużych liczb? 14

Rozwiązanie problemu 3 Wartości t 0 oraz p obliczamy stosując algorytm potęgowania modularnego: h=1; for (i=0; i<m; i++) // obliczamy h=d m-1 % q h=(d*h) % q; p = 0; ts = 0; // obliczamy wartości t 0 oraz p for (i = 0; i<m ; i++) p = (d*p+p[i]) % q; ts = (d*ts + T[i]) % q; Algorytm Rabina-Karpa w wersji Las Vegas h=1; for (i=0; i<m; i++) h=(d*h) % q; p = 0; ts = 0; for (i = 0; i<m ; i++) p = (d*p+p[i]) % q; ts = (d*ts + T[i]) % q; for (s = 0; s<=n-m; s++) bool=0; if (p = = ts) i=0; bool=1; 15

while (i < m && bool) if (P[i]!=T[s+i]) bool = 0; i++; if (bool) wzorzec P występuje w tekście T z przesunięciem s ; if (s < n-m) ts=(ts+d*q-t[s]*h) % q; ts=(ts*d+t[s+m])% q; 16