(KMP) algoritmus (Prezentáció

Download Report

Transcript (KMP) algoritmus (Prezentáció

KMP (mintaillesztés)
Gubicza József (GUJQAAI.ELTE)
Az algoritmus
• Hasonlóan működik mint a Brute Force
algoritmus, ám kihasználja a mintában levő
prefix-suffix kapcsolatokat (ha vannak), így ha egy
szöveg vizsgálata elromlik bizonyos karakternél,
nem feltétlen kell a vizsgálatot a minta elejétől
újrakezdeni. Csak a megfelelő prefixel kell odébb
tolni a mintát, az „elromlott” karakterhez. Példa:
Szöveg:
Minta:
BCBCBCD
BCBCD
BCBCD
Az algoritmus
• Viszont ahhoz, hogy tudjuk a mintával való
ugrás lehetséges értékeit, definiálnunk kell egy
next függvényt, amely megadja a minta egyes
kezdőszeleteire a leghosszabb egymással
egyező prefix-szuffix párok hosszát.
• Ezt a gyakorlatban egy vektorral lehet
megvalósítani, amit az
initnext(M[1..m],next[1..m-1]) eljárásban
töltünk fel. (M a minta, m hosszúsággal)
Az initnext eljárás
Az initnext gyakorlatilag a minta
elcsúsztatott keresését hajtja
végre önmagán (KMP
algoritmussal) , és közben
eltárolja a legnagyobb illeszkedő
részek hosszát.
Initnext
ABBABC
ABBABC
Mi a leghosszabb prefix, a mintában a
második karakterig tekintve?
Mivel a prefix legalább 1 hosszú kell
legyen, így az a kérdés, hogy
M[1] = M[2] ?
Next[1] = 0
Next[2] = 0
?
M[1] != M[2]
Initnext
ABBABC
Mi a leghosszabb prefix az első 3 karakterig
tekintve?
Mivel M[1] != M[2] => M[1..2] != M[2..3]
Így 2 hosszú prefix nincs.
Így az maradt a kérdés, hogy van-e egy hosszú
prefixünk? Mivel tudjuk, hogy M[1] != M[2], így
eltolva az alsó mintát a harmadik karakter alá,
láthatjuk, hogy M[1] != M[3]. Így..
Next[1] = 0
Next[2] = 0
M[1] != M[2]
Next[3] = 0
?
M[1] != M[3]
Initnext
ABBABC
ABBABC
Mi a leghosszabb prefix az első 4 karakterig?
[Felhasználva a táblázatban levő egyenlőtlenségeket.]
(3 hosszú prefix?)
M[1]!=M[2] => M[1..3] != M[2..4]
(2 hosszú prefix?)
M[1]!=M[3] => M[1..2] != M[3..4]
1 hosszú prefix vizsgálatánál, már M[1]-et nem
kell M[2] és M[3]-al összehasonlítani Így…
Next[1] = 0
Next[2] = 0
M[1] != M[2]
Next[3] = 0
M[1] != M[3]
Next[4] = 1
?
M[1] = M[4]
Initnext
ABBABC
ABBABC
Mi a leghosszabb prefix az első 5 karakterig?
[Felhasználva a táblázatban levő egyenlőtlenségeket.]
(4 hosszú prefix?)
M[1]!=M[2] => M[1..4] != M[2..5]
(3 hosszú prefix?)
M[1]!=M[3] => M[1..3] != M[3..5]
2 hosszú prefix?
Next[1] = 0
Next[2] = 0
M[1] != M[2]
Next[3] = 0
M[1] != M[3]
Next[4] = 1
M[1] = M[4]
Next[5] = 2
?
Folytatás
• Ezzel elkészült a next vektorunk!
• Értékeit felhasználva, mostmár elkezdhetünk
az algoritmuson is dolgozni.
• S lesz a szöveg (hossza n), M a minta (hossza
m), i és j az algoritmusban szereplő indexek,
valamint szem előtt tartjuk az előbb kapott
next értékeit.
A KMP
algoritmus
S:
M:
DABBABABBABC
ABBABC
(->n = 12)
(->m = 6)
Next[1..3] = 0
Next[4] = 1
Next[5] = 2
D A B B A B A B B A B C
A B B A B C
A
vizsgált
értékek:
i+1 éshogy
j+1 a szöveg második
Most
pedig
azt nézzük,
Tehát
mostmegegyezik-e
megnézzük, hogy
S szöveg
első karaktere
karaktere,
a minta
első karakterével
megegyezik
e, M minta első karakterével
(csúsztatunk).
Ezen a ponton, j := next[5],
j értéke így 2 lesz!
I
J
0
0
1
0
2
1
3
2
4
3
5
4
6
5
6
2
S:
M:
DABBABABBABC
ABBABC
D A
A
A B
A B
B
B
B
B
B
B
A
A
A
A
B
B
Ha j = m, legyen
(->n = 12)
(->m = 6)
Next[1..3] = 0
Next[4] = 1
Next[5] = 2
B A B B A B C
B C
C
C
Tehát találtunk (ezt u
k := i – (m-1) = 12 – 5 = 7 jelzi) a mintára
:= next[2],
u := Ezen
igaz a ponton, jilleszkedő
szövegrészt,
j értéke
így 0 lesz!
mégpedig
a 7.
pozíciótól
I
J
0
0
1
0
2
1
3
2
4
3
5
4
6
5
6
2
6
0
7
1
8
2
9
3
10
4
11
5
12
6