Algorytm Naiwny Ciąg znaków: A B D C E Wzorzec: A B
A B D C E A B A B D C E A B A B D C E A B A B D C E A B A B D C E A B A B D C E A B A B D C E A B
Algorytm Boyera-Moore’a (uproszczony) D Ciąg znaków: Wzorzec: A B C Okno wzorca umieszczamy na początku przeszukiwanego tekstu. Porównanie rozpoczynamy od ostatniego znaku wzorca. Znaki są różne. Dodatkowo znak D z tekstu nie występuje we wzorcu. Wzorzec przesuwamy o wielkość okna – 5 Brak zgodności – ale we wzorcu jest A A C B D A B C A C B D A B C
Okno wzorca przesuwamy tak, aby litera A z tekstu i ostatnia litera A ze wzorca zrównały się pozycjami. Porównujemy pozostałe znaki A C B D A B C A C B D A B C
Algorytm Boyera-Moore’a Wzorzec: A B C Tablica Last (indeksy poszczególnych elementów odpowiadają kodom znaków alfabetu, elementy natomiast określają ostatnie położenie danej litery we wzorcu) Przesunięcie: Index 1 2 3 Litera A B C D Wartość 4 -1 i – pozycja okna wzorca w tekście j – pozycja niezgodności okna ze wzorcem
A C B D A B C A C B D A B C ? A C B A B C Index 1 2 3 Litera A B C D Wartość 4 -1 A) Brak znaku we wzorcu, gdyż: Last['D'] = -1 , to przesunięcie wynosi: i = 0 + 4 – (– 1) = 5 A C B D A B C B) Znak jest we wzorcu gdyż: Last['A'] = 3, to przesunięcie wynosi: i = 5 + 4 – 3 = 6 C) Nigdy nie cofamy okna w lewo: Last['A'] = 3, to przesunięcie wynosi: i = 0 + 1 = 1 A C B D A B C ? A C B A B C
Funkcje haszujące Alfabet: ABC (3-znakowy) Wzorzec: CBBAB Kody znaków: A = 0, B = 1, C = 2 Podstawa: 3 (długość alfabetu) Moduł: 23 (najlepiej liczba pierwsza, niezamała) Wzorzec: CBBAB
Funkcje haszujące Łańcuch znaków: CBBABB Wzorzec: BBABB Wyznacz hash okna: H(CBBAB) = 15 Przesuń okno o jeden w prawo (okno: BBABB) Wyznacz H(BBABB) na podstawie H(CBBAB) Usuń pierwszy znak (C): Przesunięcie wszystkich znaków hasha o jedno w lewo Dodanie nowego znaku (B) Sprawdźmy: Kody znaków: A = 0, B = 1, C = 2
Algorytm Karpa-Rabina m = length(p) // lub p_len=|p| n = length(s) // lub s_len=|s| pat_hash = H(p) str_hash = H(s[0:m]) // hash pierwotnego okna i = 0 while i < n – m // dopóki mamy co przetwarzać if str_hash NOT pat_hash // jeśli hash okna jest różny od hasha wzorca i++ // przesun okno wzorca o jeden w prawo str_hash = H(s[i:i+m]) // oblicz nowy hash okna else if p == s[i:i+m] //sprawdz czy na pewno wzorzec jest na pozycji i return i //jesteśmy pewnie, że znaleźliśmy wzorzec endwhile return -1 //wzorca nie znaleziono