Knuth-Morris-Pratt-algoritm

Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från versionen som granskades den 13 oktober 2019; kontroller kräver 6 redigeringar .

Knuth-Morris-Pratt- algoritmen (KMP-algoritmen) är en effektiv algoritm som söker efter en delsträng i en sträng . Algoritmens körtid beror linjärt på mängden indata, det vill säga det är omöjligt att utveckla en asymptotiskt mer effektiv algoritm.

Algoritmen utvecklades av D. Knuth och W. Pratt och, oberoende av dem, av D. Morris [1] . De publicerade resultaten av sitt arbete gemensamt 1977 [2] .

Förklaring av problemet

Givet ett mönster (sträng) och en sträng . Det krävs att bestämma indexet från vilket mönstret finns i strängen . Om det inte ingår i  returnerar du ett index som inte kan tolkas som en position i strängen (till exempel ett negativt tal). Om du behöver hålla reda på varje förekomst av ett mönster i texten, är det vettigt att ha en extra funktion som anropas när ett mönster hittas.

Idé

Aho-Korasik-algoritmen låter dig också söka efter en enda sträng i linjär tid. Men den svaga punkten med denna algoritm är den finita automaten, som är explicit inbyggd i O (| nål |·|Σ|) operationer och kräver samma mängd minne.

Om du bara söker efter en rad kommer varje stat att ha bara en "direkt" övergång. Sidoövergångar kommer att beräknas dynamiskt, utan att cachelagra dem på något sätt.

om höstack[i] = nål[tillstånd] sedan state = state + 1 annars tillstånd = sidoövergång(tillstånd, höstack[i])

Det är lätt att se att suffixlänkarna i Aho-Korasik-algoritmen är en prefixfunktion för den önskade mallen.

Beskrivning av algoritmen och uppskattning av körtid

Överväg en strängjämförelse vid position , där mönstret matchas mot en textbit . Antag att den första missmatchningen inträffade mellan och , där . Sedan och .

När du skiftar är det fullt möjligt att förvänta sig att prefixet (starttecken) i mönstret kommer att konvergera med något suffix (sluttecken) i texten . Längden på det längsta prefixet, som också är ett suffix, är värdet på prefixfunktionen från strängen för indexet .

Detta leder oss till följande algoritm: låt  vara värdet på prefixfunktionen från strängen för index . Sedan, efter skiftet, kan vi återuppta jämförelser från platsen och utan att förlora den möjliga platsen för provet. Det kan visas att tabellen kan beräknas (amorteras) för jämförelser innan sökningen påbörjas. Och eftersom strängen kommer att korsas exakt en gång, kommer den totala körtiden för algoritmen att vara lika med , där  är längden på texten .

Pseudokod för algoritmen

funktion KMP(S, T) k ← 0 A ← ø // A - tom uppsättning π ← Prefix_Function(S) // betrakta prefixfunktionen från mönstret S för i = 1 till |T| gör // |T| - stränglängd T medan k > 0 och T[i] ≠ S[k + 1] gör det k ← π[k] avsluta medan om T[i] = S[k + 1] då k ← k + 1 sluta om om k = |S| sedan A ← A ⋃ {i - |S| + 1} // detta är om vi betraktade prefixfunktionen i början A ← A ⋃ {i} // detta är om vi först beräknade z-funktionen k ← π[k] sluta om slut för tillbaka A slutfunktion

Funktionen returnerar  — uppsättningen av antalet element i strängen som slutar de hittade förekomsterna i .

Se även

Anteckningar

  1. Kormen, T. , Leizerson, C. , Rivest, R. , Stein, K. Algoritmer: konstruktion och analys = Introduktion till algoritmer / Ed. I. V. Krasikova. - 2:a uppl. - M. : Williams, 2005. - 1296 sid. — ISBN 5-8459-0857-4 .
  2. Donald Knuth; James H. Morris, Jr, Vaughan Pratt. Snabb mönstermatchning i strängar  // SIAM  Journal on Computing : journal. - 1977. - Vol. 6 , nr. 2 . - S. 323-350 . - doi : 10.1137/0206024 .

Länkar