Etuliitetoiminto

Kokeneet kirjoittajat eivät ole vielä tarkistaneet sivun nykyistä versiota, ja se voi poiketa merkittävästi 12. huhtikuuta 2022 tarkistetusta versiosta . tarkastukset vaativat 4 muokkausta .

Merkkijonon etuliitefunktio ja paikka siinä on alimerkkijonon suurimman varsinaisen (ei yhtä suuri kuin koko osamerkkijonon) etuliitteen pituus , joka on myös tämän osamerkkijonon pääte .

Toisin sanoen pituuden alimerkkijonon alusta on löydettävä sellainen maksimipituinen etuliite, joka olisi tämän osamerkkijonon pääte .

Merkitty ; missä  on merkkijono;  on S:n osamerkkijonon pituus. Oletetaan, että .

Usein etuliitefunktio määritellään vektorimuodossa:

Merkkijonon etuliitefunktio on vektori , jonka jokainen elementti on yhtä suuri kuin .

Esimerkiksi merkkijonolle etuliitefunktio olisi: .

Tätä funktiota käytetään esimerkiksi Knuth-Morris-Pratt-algoritmissa .

Laskenta-algoritmi

Etsi toistuvia tavuja ei sanasta, vaan tekstistä, riviltä, ​​joka alkaa ensimmäisistä merkeistä? Rivimerkit numeroidaan 1:stä alkaen.

Anna . Yritetään laskea etuliitefunktio .

Jos , niin tietysti . Jos ei, kokeile pienempiä jälkiliitteitä. Lineaarisella haulla ei tarvitse iteroida kaikkia jälkiliitteitä. Voit käyttää etuliitefunktion jo laskettuja arvoja. Voit nähdä, että se on myös merkkijonon pääte , koska  se on maksimietuliite-liitteen pituus tässä vaiheessa. Millä tahansa merkkijonolla ei ole jälkiliitettä. Siten algoritmista tulee:

  1. Milloin  - laittaa .
  2. Muuten, kun  - laittaa .
  3. Muussa tapauksessa asenna ja siirry vaiheeseen 1.

Merkkijonolle 'abcdabcabcdabcdab'laskenta olisi seuraava:

1 S[1] = 'a', k = π = 0; 2 S[2]='b'!=S[k+1] => k=π=0; 3 S[3]='c'!=S[1] => k=π=0; 4 S[4]='d'!=S[1] => k=π=0; 5 S[5]='a'==S[1] => k=π=1; 6 S[6]='b'==S[2] => k=π=2; 7 S[7]='c'==S[3] => k=π=3; 8 S[8]='a'!=S[4] => k:=π(S, 3)=0, S[8]==S[1] => k=π=1; 9 S[9]='b'==S[2] => k=π=2; 10 S[10]='c'==S[3] => k=π=3; 11 S[11]='d'==S[4] => k=π=4; 12 S[12]='a'==S[5] => k=π=5; 13 S[13]='b'==S[6] => k=π=6; 14 S[14]='c'==S[7] => k=π=7; 15 S[15]='d'!=S[8] => k:=π(S,7)=3, S[15]==S[4] => k=π=4; 16 S[16]='a'==S[5] => k=π=5; 17 S[17]='b'==S[6] => k=π=6;

Ja tulos on: [0,0,0,0,1,2,3,1,2,3,4,5,6,7,4,5,6].

Työn nopeus

Huolimatta siitä, että kohta 3 on sisäsilmukka, etuliitefunktion laskenta-aika on arvioitu . Todistetaan se.

Kaikki on jaettu:

  1. kasvaa yhdellä. Silmukka käy läpi yhden iteraation.
  2. Ei vaihda nollaa . Silmukka käy myös yhden iteraation läpi. Tapaukset 1 ja 2 yhteensä enintään kappaletta.
  3. Älä muuta tai vähennä positiivista . Koska arvo voi pienentyä vain silmukan sisällä, ja lisäys on mahdollista vain yhdellä, kokonaisarvo ei voi laskea useammin kuin kerran, mikä rajoittaa sisemmän silmukan suorituskertoja.

Kaiken kaikkiaan algoritmi ei vaadi enempää kuin iteraatioita, mikä todistaa nopeuden järjestyksen . Algoritmin "pahin" on muodon merkkijonon käsittely . 'aa…ab'

Toteutusesimerkki Pythonissa

def - etuliite ( s ):     p = [ 0 ] * len ( s )     i :lle alueella ( 1 , len ( s ) ): k = p [ i - 1 ] kun taas k > 0 ja s [ k ] != s [ i ]: k = p [ k - 1 ] jos s [ k ] == s [ i ]: k += 1 p [ i ] = k paluu p                                                            

Linkit