140 likes | 221 Views
Miskolci Egyetem Informatikai Intézet Általános Informatikai Tanszé k Pance Miklós Adatstruktúrák, algoritmusok előadásvázlat Miskolc, 2004 Technikai közreműködő: Imre Mihály, műszaki informatikus hallgató. Szövegminta keresés. Legyen adott egy véges ABC, Integer , N>>M .
E N D
Miskolci Egyetem Informatikai Intézet Általános Informatikai Tanszék Pance Miklós Adatstruktúrák, algoritmusok előadásvázlat Miskolc, 2004 Technikai közreműködő: Imre Mihály, műszaki informatikus hallgató
Szövegminta keresés Legyen adott egy véges ABC,Integer , N>>M. Ekkor a szöveg Keressük az(oka)t az i értéke(ke)t, melyre esetén teljesül, hogy Ha a minták lehetséges halmaza jól behatárolt (szavak) és a szöveg változásának valószínűsége kicsi, azaz statikus szövegről van szó, akkor a keresés meggyorsítható egy a szöveghez kapcsolt indextáblával. (Az indextábla kulcs-pozíció párokat tartalmaz a kulcsérték szerinti gyors elérést biztosító struktúrában, pl. lista és bináris keresés vagy fa; a kulcs lehet szó vagy azzal ekvivalens numerikus kifejezés. ) 2
Szövegminta keresés Dinamikus szövegeknél az indextáblát gyakran kell frissíteni, s ez növeli a műveleti időt. A változások miatt az indextábla nagy része feleslegessé válhat. Közvetlen keresést kell alkalmazni. Elemi, naiv eljárások: - a szöveg minden karakterére ráillesztjük a mintát és a minta betűin végighaladva ellenőrizzük, hogy megegyezik-e a mintabeli és a szövegbeli karakter. Ez összesen (N-M)M összehasonlítást igényel: O(N*M) - javítás: csak addig megyünk, amíg eltérést vagy mintavéget nem találunk. Ekkor a keresési idő jelentősen függ a minta alakjától és O(N+M) és O(N*M) a hatékonyság, általában O(L*N) L> 1 3
Szövegminta keresés Ezek a módszerek úgynevezett felejtő eljárások, mivel nem hasznosítják az előző illesztések során szerzett információkat. 4
ai-j+1 b1 ai bj ai-j+2 b2 szöveg minta Szövegminta keresésKMP Az alapelv: ha az illesztésnél a minta j. pozícióján volt először eltérés, akkor a szöveg és a minta előző (j-1) karaktere azonos volt. Ezt felhasználva határozzuk meg mennyit léphetünk előre. Ha ismerjük a minta felépítését, akkor felesleges mindig vissza menni az (i-j+2)-ik szövegkarakterre, hogy azt újból összehasonlítsuk a minta első karakterével. Akkor ugorhatunk nagyobb lépést, ha tudjuk van-e és milyen hosszú ismétlődő rész a minta vizsgált részének elején és végén. 5
Szövegminta keresésKMP Tegyük fel, hogy l hosszúságú a leghosszabb ilyen ismétlődő rész a minta 1..(j-1) közötti szakaszán. l 6 4 4 7 4 4 8 l 6 4 4 7 4 4 8 bj j' x x 1 4 4 4 4 4 4 4 2 4 4 4 4 4 4 4 3 j - 1 Ha l=0, akkor a szöveg ezen része átugorható és a szöveg i-edik elemét vizsgálhatjuk a minta 1. elemével. Ha j=1 lenne, akkor ez már megtörtént, ilyenkor a szövegben egyet előre lépve az (i+1)-edikelemet vizsgáljuk a minta első elemével. 6
Szövegminta keresésKMP Ha l > 0, akkor a minta csak (j-1-l) elemmel tolható el, azaz a j’ = l+1 indexű mintaelemet kell a szöveg i. elemével összehasonlítani. Egy adott j-hez tartozó j’-t next(j) - nek is nevezik. A next(j) függvény értéke, amit tömbként is tárolhatunk, csak a mintától függ. A next[j] meghatározásának egyik naív módszere lehetne, hogy minden lehetséges l-et növekvő értékkel kipróbálunk, amíg elérjük a maximumot. Egy iteratív módszer: Tegyük fel adott k-ra ismerjük next(k) –t. 7
minta bk bnext[k] bk+1 Szövegminta keresésKMP Ha eggyel növeljük k értékét, akkor ha bk = bnext[k] akkor egy l+1 hosszú ismétlődő részt kaptunk, azaz next(k+1) = next(k) + l. Ha viszont bk<>bnext[k] , akkor egy rövidebb ismétlődést kell vizsgálni, amely az l szakasz ismétlődése lehet csak. Ellenőrizzük, hogy bk = bnext[next[k]],ha igen akkor megvan az új hossz, azaz next[k+1] = next[ next[k]] + 1. Ha nem akkor iteratívan tovább megyünk a next[next[.......[k]].....] kifejezéssel míg sikerül egyezést találni, vagy már csak egyelemű a vizsgált ismétlődő rész, ekkor next[k+1] = 1. 8
Szövegminta keresésKMP A Next tömb előállítása: j = 1; Next[j] = 0; k = 0; while (j < M) { if (b[j] = b[k] || k = 0) { j++; k++; Next[j] = k; } else k = Next[k]; } 9
Szövegminta keresésKMP A keresés: i = 1; j = 1; while ( i <= N && j <= M) { if (a[i] = = b[j] || j = = 0) { i++; j++; } else j = next[j]; if ( j > M) {OK} else {nem talált} } 10
Szövegminta keresésKMP Pl. a: BARBA b: ABBA NEM BARBA DE .... 1 2 3 4 5 B A R B A j = 1 k = 0 Next[1] = 0 j = 2 k = 1 Next[2] = 1 k = 0 j = 3 k = 1 Next[3] = 1 k = 0 j = 4 k = 1 Next[4] = 1 j = 5 k = 2 Next[5] = 2 BAKOS BAROKK BARBI BARBA BARBA BARBA BARBA BARBA BARBA 11
Szövegminta keresésQS Quick Search (QS) ABBARAKRA BARBA Shift[A] = 1, B = 2, C = 6, ... R= 3. Az adott betű milyen távol található a minta végétől. Ha x (a szöveg éppen vizsgált karaktere) nincs a mintában, akkor utána tolom a mintában, ha benne van, akkor annyira, hogy az x fedésbe kerüljön a mintabeli utolsó előfordulásával. 12
Szövegminta keresés QS A shift kitöltése: For(i = 1; i < 256; i++) Shift[i] = M + 1; For(i = 1; i <= M; i++) Shift[ TM[i] ] = M – i + 1; 13
Szövegminta keresés QS A keresés: k = 1; while(k <= N – M + 1) { j = 1; i = k; while(TT[i] == TM[j] && j <= M) { i++; j++; } if (j > M) {OK} else k += shift[ TT[ k + j ] ] } 14