Hledání v textu algoritmem Boyer Moore

Podobné dokumenty
Metodický koncept k efektivní podpoře klíčových odborných kompetencí s využitím cizího jazyka ATCZ62 - CLIL jako výuková strategie na vysoké škole

Suffixové stromy. Osnova:

Základy algoritmizace. Pattern matching

Katedra počítačů FEL

ZADÁNÍ BAKALÁŘSKÉ PRÁCE

LinuxDays 2017 Ondřej Guth GNU grep LD 17 1 / 14

1. Pojmy a definice. 2. Naivní algoritmus. 3. Boyer Moore

Vyhledávání v textu. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava

Vyhledávání řetězců. a b a c a a b. a b a c a b. a b a c a b

Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague

Konstrukce relace. Postupně konstruujeme na množině všech stavů Q relace i,

Hranová konzistence. Arc consistency AC. Nejprve se zabýváme binárními CSP. podmínka odpovídá hraně v grafu podmínek

Dijkstrův algoritmus

63. ročník Matematické olympiády 2013/2014

PQ-stromy a rozpoznávání intervalových grafů v lineárním čase

TGH06 - Hledání nejkratší cesty

TGH06 - Hledání nejkratší cesty

Elegantní algoritmus pro konstrukci sufixových polí

10 Důkazové postupy pro algoritmy

Naproti tomu gramatika je vlastně soupis pravidel, jak

5 Orientované grafy, Toky v sítích

Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague

Vrcholová barevnost grafu

Nechť je číselná posloupnost. Pro všechna položme. Posloupnost nazýváme posloupnost částečných součtů řady.

Algoritmus pro hledání nejkratší cesty orientovaným grafem

Množinu všech slov nad abecedou Σ značíme Σ * Množinu všech neprázdných slov Σ + Jazyk nad abecedou Σ je libovolná množina slov nad Σ

Union-Find problém. Kapitola 1

4.2.5 Orientovaný úhel II. π π = π = π (není násobek 2π ) 115 π není velikost úhlu α. Předpoklady: Nejdříve opakování z minulé hodiny.

Algoritmizace Dynamické programování. Jiří Vyskočil, Marko Genyg-Berezovskyj 2010

Principy indukce a rekursivní algoritmy

Kongruence na množině celých čísel

Rovnice se separovanými proměnnými

FIT ČVUT MI-LOM Lineární optimalizace a metody. Dualita. Evropský sociální fond Praha & EU: Investujeme do vaší budoucnosti

= je prostý orientovaný graf., formálně c ( u, v) 0. dva speciální uzly: zdrojový uzel s a cílový uzel t. Dále budeme bez

Paralelní grafové algoritmy

Vlastnosti regulárních jazyků

Úlohy nejmenších čtverců

doplněk, zřetězení, Kleeneho operaci a reverzi. Ukážeme ještě další operace s jazyky, na které je

TGH05 - aplikace DFS, průchod do šířky

Zobecněný Riemannův integrál

Programování. s omezujícími podmínkami. Roman Barták. rová hranová konzistence

- funkce, které integrujete aproximujte jejich Taylorovými řadami a ty následně zintegrujte. V obou případech vyzkoušejte Taylorovy řady

Statistická teorie učení

- znakové konstanty v apostrofech, např. a, +, (znak mezera) - proměnná zabírá 1 byte, obsahuje kód příslušného znaku

Teoretická informatika - Úkol č.1

1 Linearní prostory nad komplexními čísly

3 Bodové odhady a jejich vlastnosti

10 Přednáška ze

Obecná informatika. Matematicko-fyzikální fakulta Univerzity Karlovy v Praze. Podzim 2012

Formální systém výrokové logiky

Rekurze a rychlé třídění

TGH05 - aplikace DFS, průchod do šířky

: Teoretická informatika(ti)

V každém kroku se a + b zmenší o min(a, b), tedy vždy alespoň o 1. Jestliže jsme na začátku dostali 2

Algoritmus pro generování normálních magických čtverců

(Pattern Matching) a b a c a a b. a b a c a b. a b a c a b

Zpracoval: 7. Matematická indukce a rekurse. Řešení rekurentních (diferenčních) rovnic s konstantními koeficienty.

NÁVOD NA VYROBENÍ PERSPEKTIVNÍ KRABIČKY

Riemannův určitý integrál

Minimalizace KA - Úvod

PŘEDNÁŠKA 2 POSLOUPNOSTI

AUTOMATY A GRAMATIKY. Pavel Surynek. Kontextové uzávěrové vlastnosti Turingův stroj Rekurzivně spočetné jazyky Kódování, enumerace

Testování prvočíselnosti

Programování I. Martin Pergel,

4.2.5 Orientovaný úhel II

f(c) = 0. cn pro f(c n ) > 0 b n pro f(c n ) < 0

Výroková a predikátová logika - IV

7 Ortogonální a ortonormální vektory

Intervalové stromy. Představme si, že máme posloupnost celých čísel p 0, p 1,... p N 1, se kterou budeme. 1. Změna jednoho čísla v posloupnosti.

Slovní úlohy I

GRAFY A GRAFOVÉ ALGORITMY

Test prvočíselnosti. Úkol: otestovat dané číslo N, zda je prvočíslem

Složitost Filip Hlásek

MATEMATICKÁ OLYMPIÁDA NA STŘEDNÍCH ŠKOLÁCH

Modely Herbrandovské interpretace

M - Příprava na 1. zápočtový test - třída 3SA

popel, glum & nepil 16/28

Algoritmy a datové struktury

Afinita je stručný název pro afinní transformaci prostoru, tj.vzájemně jednoznačné afinní zobrazení bodového prostoru A n na sebe.

TOPOLOGIE A TEORIE KATEGORIÍ (2017/2018) 4. PREDNÁŠKA - SOUČIN PROSTORŮ A TICHONOVOVA VĚTA.

Binární vyhledávací stromy pokročilé partie

M - Příprava na pololetní písemku č. 1

Z. Sawa (VŠB-TUO) Teoretická informatika 5. listopadu / 43

Teorie množin Pavel Podbrdský

Poslední nenulová číslice faktoriálu

Variace. Mocniny a odmocniny

Příklad síťového adresování

Metody výpočtu limit funkcí a posloupností

Inovace a zkvalitnění výuky prostřednictvím ICT Základy programování a algoritmizace úloh Třídění dat. Ing. Hodál Jaroslav, Ph.D. VY_32_INOVACE_26 04

65. ročník Matematické olympiády 2015/2016

Základní pojmy matematické logiky

Místo pojmu výroková formule budeme používat zkráceně jen formule. Při jejich zápisu

Programování 3. hodina. RNDr. Jan Lánský, Ph.D. Katedra informatiky a matematiky Fakulta ekonomických studií Vysoká škola finanční a správní 2015

P 1 = P 1 1 = P 1, P 1 2 =

Nalezněte obecné řešení diferenciální rovnice (pomocí separace proměnných) a řešení Cauchyho úlohy: =, 0 = 1 = 1. ln = +,

Dynamické programování

Nyní využijeme slovník Laplaceovy transformace pro derivaci a přímé hodnoty a dostaneme běžnou algebraickou rovnici. ! 2 "

1.3. Číselné množiny. Cíle. Průvodce studiem. Výklad

Výhody a nevýhody jednotlivých reprezentací jsou shrnuty na konci kapitoly.

Úloha - rozpoznávání číslic

Transkript:

Zápočtová práce z Algoritmů a Datových Struktur II (NTIN061) Hledání v textu algoritmem Boyer Moore David Pěgřímek http://davpe.net

Algoritmus Boyer Moore[1] slouží k vyhledání vzoru V v zadaném textu T. Stejně jako v naivním algoritmu je vzor zarovnán se začátkem textu, avšak porovnává se zprava. V případě neúspěchu navrhnou dvě heuristiky počet pozic, o které by se měl vzor posunout doprava. Algoritmus si vybere větší z navržených posunů. Nadále budeme značit délku vzoru V jako V a délku textu T jako T. Všechna pole jsou indexována od jedničky, pokud není řečeno jinak. Posun při špatném znaku (Bad character shift) Představme si, že právě zprava porovnáváme vzor textem a na pozici t textu T se znak c = T [t] liší od právě porovnávaného znaku vzoru na místě v. Pak mohou nastat tyto možnosti. 1. Znak c ve vzoru vůbec nevyskytuje, nemá smysl se pozicí t zabývat. Posuneme tedy vzor tak, aby jeho první znak byl těsně za pozicí t v textu. 2. Znak c ve vzoru vyskytuje jen a pouze nalevo od V [v]. Vezměme znak c = V [u], který je nejblíže k V [v]. Pak nás znaky mezi V [u] a V [v], nebudou zajímat, neboť každý z nich selže. Proto posuneme vzor doprava tak, aby znak V [u] byl právě pod znakem T [t]. 3. Znak c ve vzoru vyskytuje nalevo i napravo od V [v]. Dávalo by smysl posunout vzor stejně jako v předchozím případě. Bohužel, museli bychom si pamatovat všechny pozice znaku c, což by nám algoritmus zpomalilo. Posuneme vzor jen o jednu pozici doprava a spolehneme se na druhou heuristiku. _ D R A K S O U M R A K S O U M R A K 1. Znak c =D se ve vzoru nevyskytuje. _ B A B A B A R B A R A B A R B A R A 2. Znak c =B je ve vzoru jen vlevo, posouváme na znak B. K A T K A _ K A R I M A T K A K A R I M A T K A 3. Znak c =K je ve vzoru i vpravo, posouváme o jednu pozici. Obrázek 1: Příklady posunů při špatném znaku. Abychom poznali, o kolik znaků vzor posunout budeme si pro něj pamatovat pole bcs indexované abecedou Σ, se kterou pracujeme (v našich příkladech to budou písmena A Ž a mezera) definovanou takto { V i pokud V [i] = c i V i je maximální možné bcs[c] = V pokud V [V] = c c / V Jinými slovy hodnota bcs[c] je počet znaků mezi posledním výskytem písmene c ve vzoru a místem za koncem vzoru. Pokud písmeno c je na posledním místě vzoru, nebo v něm vůbec není bude hodnota rovna délce vzoru. Proč právě tyto hodnoty? Představme si, že selhalo hned první písmeno c, které jsme porovnávali (tedy poslední písmeno současného prefixu textu). Pak hodnota, o kterou musíme vzor posunout, abychom nám už znak c neselhal je právě bcs[c]. Pokud už jsme úspěšně porovnali s znaků (délka úspěšně porovnaného sufixu vzoru je s), posuneme vzor doprava o hodnotu bcs[c] - s (pokud vyjde posun záporně, je to třetí případ a posuneme vzor jen o jednu pozici). A K M O R S U * 1 7 3 5 2 6 4 7 Posun vzoru doprava o bcs[d] s = 7 3 = 4 A B R * 2 3 1 7 Posun vzoru doprava o bcs[b] s = 3 1 = 2 A I K M R T * 3 5 1 4 6 2 9 Posun bcs[k] s = 1 4 = 3 je záporný, posouváme o 1 Obrázek 2: Tabulky bcs pro příklady výše (znaky nevyskytující se ve vzoru jsou označeny hvězdičkou).

Algoritmus pro vyplnění pole bcs bcs[σ] V for i = 1 to V 1 do bcs[v[i]] V i Na začátku nastavíme všech znakům hodnotu V. Poté procházíme vzor zleva a nastavíme hodnotu bcs pro znak V [i] na V i. Správnost algoritmu je zřejmá z definice bcs. Časová složitost je O( Σ + V), paměťová složitost je O( Σ ). Posun při správném sufixu (Weak good-suffix shift) Představme si, že při porovnávání vzoru zprava s textem jsme již úspěšné porovnali sufix V [s],..., V [V], ale znak c = V [s 1] už selhal. Heuristika good-suffix se ve vzoru snaží najít podřetězec, který by byl stejný (nebo kratší) jako úspěšně porovnaný sufix. 1 1. Najdeme ve vzoru stejný podřetězec, jako úspěšně porovnaný sufix (tedy V [s],..., V [V]). Poté posuneme vzor doprava tak, aby pod původním úspěšně porovnaným sufixem byl nově nalezený sufix. Budeme tak mít zaručeno, že už máme úspěšně porovnáno s znaků. 2. Pokud takový řetězec neexistuje, najdeme nejdelší prefix vzoru, který je sufixem úspěšně porovnaného sufixu. P O K U S _ K U S K U S U K U S K U S K U S U K U S 1. Najdeme ve vzoru nejbližší řetězec KUS. P O V L A K A K Č N Í V L A K A K Č N Í V L A K 2. Nejdelší prefix vzoru AK, který je sufixem vzoru. Oproti předchozí heuristice je tato o něco složitější a její algoritmus má dvě části. V první části si vyrobíme pole pref a ferp. Na pozici pref[i] bude velikost nejdelšího prefixu vzoru, který je vlastním sufixem V [1..i]. Na pozici ferp[i] bude to samé co na pozici pref[i] pro vzor napsaný pozpátku. Budeme jej značit V rev. Ve druhé části tato pole použijeme ke zkonstruování finálního pole gss. Na jeho i-tém místě bude nejmenší počet pozic, o které musíme vzor posunout doprava, abychom na místo V [i+1..v] (což je úspěšně porovnaný sufix) nebo jeho sufixu dostali stejný řetězec. 0 1 2 3 4 5 6 7 8 9 10 11 V K U S K U S U K U S pref 0 0 0 1 2 3 0 0 1 2 3 ferp 0 0 0 0 0 1 2 3 1 2 3 gss 8 8 8 8 8 8 8 8 5 5 5 8 1. Posun vzoru o gss[7]=5. 0 1 2 3 4 5 6 7 8 9 10 V A K Č N Í V L A K pref 0 0 0 0 0 0 0 0 1 2 ferp 0 0 0 0 0 0 0 0 1 2 gcs 8 8 8 8 8 8 8 8 8 8 8 1. Posun vzoru o gss[5]=8. Počítání polí pref a ferp Nadefinujeme si formálně obě pole. pref[i] = max({k : V [1..k] je vlastní sufix V [1..i]}) ferp[i] = max({k : V rev [1..k] je vlastní sufix V rev [1..i]}) Funkci, která počítá pole pref nazveme π. A dokonce už ji známe; je to stejná funkce, která v KMP automatu konstruuje zpětné hrany a máme o ní i dokázáno, že běží v čase O(V). Pole ferp získáme jednoduše, stačí funkcí π předat vzor, který je pozpátku. Budeme jej značit V rev. 1 Existuje silnější varianta zvaná Strong good suffix shift. Není součástí původního algoritmu, avšak umožňuje dokázat jeho linearitu. Přidává navíc podmínku, že se před nově nalezeným podřetězcem nesmí vyskytovat znak c.

Počítání gss Nejprve si nadefinujeme pole gss. Poté budeme pomocí různých pozorování definici upravovat, až vytvoříme základ pro algoritmus počítající jeho hodnoty. gss[i] = V max({k : 0 k < V V [i + 1..V] je sufix V [1..k] nebo naopak}) Pozorování: Platí i : gss[i] V pref[v]. Důkaz: Upravme nerovnici na tvar V k V pref[v], kde k pochází z definice gss a je maximální. Pak k pref[v 1 ] což platí, neboť prefix vzoru V délky k, jehož sufix je i sufixem V je zjevně delší, než prefix vzoru V, který je sufixem vzoru V. Dále si všimneme, že pokud v poslední podmínce definice gss platí varianta V [0..k] je sufixem V, pak k pref[v]. Dle předchozího pozorování nám tento případ hodnoty gss nezmění a můžeme jej zanedbat. Upravme si definici gss. gss[i] = V max({pref[v]}, {k : pref[v] < k < V V [i + 1..V] je sufix V [1..k]}) Tvrzení: Nechť V [i + 1..V] je sufix V [1..k] a k je největší takové. Pak ferp[l] = V i, kde l = (V k) + (V i). Důkaz: Neboť V [i+1..v] je sufix V [1..k] pak zřejmě V rev [1..V i] je sufix V rev [1..l]. Pak ferp[l] V i. Nechť pro spor p > V i kde p = ferp[l]. Z definice ferp plyne V rev [1..p] je sufix V rev [1..l], což je ekvivalentní tomu, že V rev [1..p] = V rev [l p + 1..l]. Přepíšeme-li tento vztah z rev tvaru do běžného, dostaneme V [V p + 1..V] = V [V l + 1..V l + p]. Nyní provedeme substituci pro l = 2V k i a dostaneme V [V p + 1..V] = V [k V + i + 1..k V + i + p]. To znamená, že V [V p + 1..V] je sufix V [1..k V + i + p]. Neboť p > V i pak i + 1 > V p + 1 a V [i + 1..V] je sufix V [V p + 1..V]. Z tranzitivity sufixů plyne V [i + 1..V] je sufix V [1..k V + i + p]. Neboť p > V i, pak jsme našli k > k, kde k = k V + i + p což je spor s maximalitou k. Využijeme předchozí tvrzení a se znalostí, že i = V ferp[l] a k = V l ferp[l] naposledy upravíme definici gss a předvedeme algoritmus na jeho spočtení. gss[i] = V max({pref[v]}, {V l ferp[l] : 1 l V i = V ferp[l]}) = min({v pref[v]}, {l ferp[l] : 1 l V i = V ferp[l]}) Algoritmus pro vyplnění pole gss pref π(v ) ferp π(v rev ) for i = 0 to V do gss[i] V pref[v] for l = 1 to V do i V ferp[l] if gss[i] > l ferp[l] then gss[i] l ferp[l] end if Správnost algoritmu plyne z tvrzení a pozorování výše, časová i paměťová složitost je zřejmě O(V).

Algoritmus Boyer Moore Pseudokód samotného algoritmu je uveden níže. Předpokládá, že pole bcs a gss pro obě heuristiky již máme předpočítané. t 0 while t T V do v V while v > 0 V [v] = T [t + v] do v v 1 end while if v = 0 then print Vzor se v textu vyskytuje na pozici t t t + gss[0] else t t + max(gss[v], bcs[t [t + v]] (V v), 1) end if end while Správnost algoritmu plyne ze správnosti obou heuristik. Časová složitost je podobná jako u naivního algoritmu O(T V + Σ ), v praxi je však algoritmus mnohem rychlejší. Uveďme ještě dolní, daleko zajímavější odhad časové složitosti Ω(T /V). Příkladem budiž text, tvořený samými písmeny A a vzor tvořený písmeny B. Paměťová složitosti je O(T + V). Reference [1] R. S. Boyer and J. S. Moore. A fast string searching algorithm. Communications of ACM, 20(10):762-772, 1977