LCP niz

S Vikipedije, slobodne enciklopedije
LCP niz
Tip niz
Pronalazač Manber & Myers 1990
Vremenska i prostorna složenost
u veliko O notaciji
Prosečan slučaj Najgori slučaj
Prostor
Vreme

U informatici, najduži zajednički prefiks niz (eng. longest common prefix array) je pomoćna struktura podataka pri sufiksnom nizu. Ona čuva dužine najdužih zajedničkih prefiksa, između parova uzastopnih sufiksa u sortiranom sufiksnom niza. Drugim rečima, to je dužina prefiksa zajednička za dva uzastopna sufiksa u sortiranom nizu sufiksa.

Primer:

LCP od a i aabba je 1.

LCP od abaabba i abba je 2.

Povećavajući sufiksni niz sa LCP nizom omogućava efikasno simuliranje odozgo nadole i odozdo nagore obilazak stabla za sufiksno stablo, obrazac poklapanja kod sufiksnog niza i preduslov je za komprimovano sufiksno stablo.

Istorija[uredi | uredi izvor]

LCP niz su zajedno sa sufiksnim nizom uveli, 1993. godine, Udi Manber i Gene Myers sa ciljem da poboljšaju vremensku složenost alogoritma pretrage niza stringova. Gene Myers je bivši potpredsednik Informatics Research u Celera Genomics, a Udi Manber je bio potpredsednik inženjering u Google.

Definicija[uredi | uredi izvor]

Neka je sufiksni niz niza stringova i neka označava dužinu najdužeg zajedničkog prfiksa između dva stringa i . Označimo dodatno sa podniz od u rasponu od do .

Tada je LCP niz ceo niz dužine, tako da je nedefinisan i za svako . Tako da čuva dužinu najdužeg zajedničkog prefiksa od leksikografski i-tog najmanjeg zajedničkog sufiksa i njegov prethodnik u nizu sufiksa.

Primer[uredi | uredi izvor]

Razmotrimo string :

i 1 2 3 4 5 6 7
S[i] b a n a n a $

i odgovarajući sufiksni niz  :

i 1 2 3 4 5 6 7
A[i] 7 6 4 2 1 5 3

Kompletan sufiksni niz sa samim sufiksom :

i 1 2 3 4 5 6 7
A[i] 7 6 4 2 1 5 3
1 $ a a a b n n
2 $ n n a a a
3 a a n $ n
4 $ n a a
5 a n $
6 $ a
7 $

Tada je LCP niz konstruisan poređenjem leksikografski uzastopnih sufiksa da bi se utvrdio njihov najduži zajednički prefiks:

i 1 2 3 4 5 6 7
H[i] 0 1 3 0 0 2

Npr., je dužina najdužeg zajedničkog prefiksa podeljena sufiksima i . Treba imati u vidu da je , dokle god nema leksikografski manjeg sufiksa.

Razlika između sufiksnog niza i LCP niza[uredi | uredi izvor]

Sufiksni niz: Predstavlja leksikografks rang svakog sufiksa niza.

LCP niz: Sadrži maksimalnu dužina prefiksa koji se poklapa između dva uzastopna sufiksa, nakon što su sortirani leksikografski.

Upotreba LCP niza u pronalaženju broj pojava obrasca[uredi | uredi izvor]

U cilju nalaženja broj pojavljivanja datog string P (dužina m) u tekstu T (dužine N),

  • Mora se koristiti binarna pretraga za sufiks dužine T.
  • Trebalo bi se ubrzati primenom LCP niza kao pomoćne strukture podataka. Preciznije, trebalo bi napraviti posebnu verziju LCP niza (LCP-LR niz) i koristiti takav niz.

Problem sa korišćenjem standardne binarne pretrage (bez LCP niza) je da se u svakom od O(log N) poređenja koja su potrebna da bi uporedili P važećim ulaznim sufiksom niza, prolazimo m karaktera. Dakle, složenost je O(m*log N).

LCP-LR niz poboljšava složenost do O(m+log N), na sledeći način:

U bilo kom trenutku tokom binarne pretrage, vi smatrate, kao i obično, niz (L,...,R)sufiksom niza i njegova centralna tačka M, odlučite da li nastaviti pretragu u levom podnizu (L,...,M) ili u desnom podnizu (M,...,R). Da bi doneli odluku, uporedite P sa stringom u M. Ako je P identičan M, gotovo, ali ako nije, imaćete u odnosu na prvih K karaktera P a zatim odlučiti da li je P leksikografski manje ili veća od M. Pretpostavimo ishod je da je P veći od M. Dakle, u sledećem koraku, vi smatrate (M,...,R) i nova centralna tačka M' u sredini:

             M ...... M' ...... R
             |
      знамо:
         lcp(P,M)==k

Trik je u tome da je LCP-LR unapred određeno kao što O(1) -ukazuje na najduži zajednički prefiks M i M', lcp(M,M').

Već iz prethodnog koraka znamo lcp(P,M)=k.da i sam M ima prefiks zajedničkih likova sa P. Sada postoje tri mogućnosti:

  • Slučaj 1: k < lcp(M,M'), tj. R ima manje prefiksnih karaktera zajedničkih sa M nego što ima M sa M'. Ovo znači (k+1)-vi karakter M' je isti kao kod M, a pošto P leksikografski veća od M, onda mora biti leksikografski veće i od M'. Tako smo i dalje u desnoj polovini (M',...,R).
  • Slučaj 2: k > lcp(M,M'), tj. P ima više prefiksnih karaktera zajedničkih sa M nego M sa M'. Prema tome, ako smo za poređenje P na M', zajedničkih prefiksa, manje od K i M' biće leksikografski veća od p, tako, bez upoređenja, nastavljamo u levoj polovini (M,...,M').
  • Slučaj 3: k == lcp(M,M'). Tako ako su M i M' oba identični sa P u prvih k karaktera. Da bi se odlučilo da li ćemo nastaviti sa leve ili desne strane, dovoljno je uporediti P na M', počevši od (k+1)-og karaktera.
  • Nastaviti rekurzivno.

Sveukupni učinak je da se nijedan karakter p ne poredi sa bilo kojim karakterom iz teksta više od jednog puta. Ukupan broj poređenja karaktera je ograničen m, tako da je ukupna složenost zaista O(m+log n).

Očigledno, preostalo je još ključno pitanje kako smo odredili LCP-LR tako da nam složenost LCP-a između bilo koja dva upisa u sufiksnom nizu bude O(1)? Kao što je rečeno, standardni LCP niz govori nam samo da imamo LCP uzastopnih ulazaka, odnosno LCP (x-1, x) za bilo koje x. Ma da, M i M' u opisu iznad nisu ključno uzastopni ulazi, pa kako smo onda to učinili?

Ključno za to je da shvatimo da se određeni rasponi (L,...,R) nikada neće pojaviti tokom binarne pretrage: ona uvek počinje sa (0,...,n) i deli na sredini, a zatim dalje bilo levo ili desno i onda opet podeli tu polovinu. Ako razmišljamo o tome: svaki ulazak sufiksom niz nastaje kao centralna tačka tačno jednog mogućeg raspona tokom binarne pretrage. Dakle, postoji tačno n različitih raspona (L...M...R) koji eventualno mogu igrati ulogu u binarnom pretraživanju, a dovoljno je odrediti lcp(L,M) i lcp(M,R) za onih N mogućih raspona. Tako da imamo 2*N različitih, unapred izračunatih vrednosti, pa je LCP-LR složenosti O(N).

Osim toga, tu je jednostavan algoritam za određivanje 2xN vrednosti LCP-LR u vremenu O(N) za standardne LCP nizove.

Da sumiramo:

  • Moguće je izračunati LCP-LR u vremenu O(N) i O(2*N)=O(N) prostoru za LCP.
  • Korišćenje LCP-LR tokom binarne pretrage ubrzava postupak sa O(M*log N) to O(M+log N).
  • Mogu se koristiti dve binarne pretrage da bi se odredio levi i desni kraj opsega za podudaranje P, a dalji opseg podudaranja odgovara broju pojavljivanja za P.

Efikasna konstrukcija algoritma[uredi | uredi izvor]

Algoritmi za konstrukciju LCP niza mogu se podeliti na dve kategorije: algoritmi koji izračunavaju LCP niz kao nusprodukt u sufiksnom nizu i algoritmi koji koriste već izgrađeni sufiksni niz kako bi izračunali LCP vrednosti.

Manber & Myers 1993 aju algoritam za računanje LCP niza uz sufiksni niz u vremenu. Kärkkäinen & Sanders 2003 pokazuju da je moguće modifikovati njihovo vreme algoritma, a da pri tom jednako dobro izračunava LCP niz. Kasai et al. 2001 predstavljaju prvi algoritam u vremenu, algoritam (FLAAP), koji izračunava LCP niz u odnosu na tekst i sufiksni niz. Pod pretpostavkom da je svaki tekstualni simbol veličine jednog bajta i svaki ulazak u sufiksni ili LCP niz traje 4 bajta, glavni nedostatak njihovog algoritma je to što je popunjen veliki prostor bajtova, dok izvorni izlaz (tekst, sufiksni ili LCP niz) zauzima samo bajtova. Tako da je Manzini 2004 apravio bolju verziju algoritma Kasai et al. 2001 (lcp9) i sa kojim je smanjio količinu popunjenog prostora za bajtova. Kärkkäinen, Manzini & Puglisi 2009daju jedan još bolji Kasai's algoritam (-algoritam) koji poboljšava potrebno vreme. Umesto stvarnog LCP niza, ovaj algoritam gradi permutovani LCP (PLCP) niz, u kojem su vrednosti koje se pojavljuju u tekstu u leksikografskom poretku. Gog & Ohlebusch 2011 daju dva algoritma, koji iako su spori u teoriji (), u praksi su dosta brži.

Od 2012. godine, trenutno najbrži, linearnog vremena, algoritma za konstrukciju LCP niza je Fischer 2011, koji se temelji na jednom od najbržih algoritama za konstrukciju sufiksnog niza Nong, Zhang & Chan 2009.

Aplikacije[uredi | uredi izvor]

Kao što je navedeno od strane Abouelhoda, Kurtz & Ohlebusch 2004 nekoliko problema se može rešiti upotrebom sledećih vrsta obilazaka stabla:

  • odozdo prema gore obuhvatanjem celokupnog sufiksnog stabla
  • odozgo prema dole obilazak podstabla sufiksnog stabla
  • Obilazak sufiksnog stabla pomoću sufiksnih linkova.

Kasai et al. 2001 pokazuju kako simulirati odozdo prema gore obilazak sufiksnog stabla, korišćenjem samo sufiksnog i LCP niza. Abouelhoda, Kurtz & Ohlebusch 2004 su poboljšali sufiksni niz sa LCP nizom i dodatnom strukturom podataka, i opisali kako se poboljšani sufiksni niz može koristiti za simulaciju sva tri obilaska sufiksnog stabla. Fischer & Heun 2007 smanjuje zahteve za prostorom od strane poboljšanog sufiksnog niza sa predizračunatim LCP nizom za raspon minimalnih upita . Dakle, svaki problem koji se može režiti algoritmom za sufiksno stablo, može se rešiti i sa poboljšanim sufiksnim stablom. [1]

Odlučivanje, ako je uzorak dužine podniza stringova dužine traje vremena, ako se koristi samo sufiksni niz. Dodatno korišćenjem LCP, ovo može biti poboljšano na .[2] Abouelhoda, Kurtz & Ohlebusch 2004 pokazuju kako poboljšati ovo vreme i dalje kako bi se postigla optimalna složenost time. Dakle, pomoću sufiksnog niza i LCP niza, odabrani upiti može odgovarati jednako brzo kao i primenom sufiksnog stabla.

LCP niz je bitan deo komprimovanih sufiksnih stabala koji pruža punu funkcionalnost sufiksnim stablima kao sufiksnih linkova i najvažnijeg zajedničkog pretka upita. Osim toga može se koristiti zajedno sa sufiksnim nizom za izračunavanje Lempel-Ziv LZ77 faktorizacije u vremenu. [1][3][4][5]

Problem najduže ponavljanog podniza za niz dužine može biti rešen u vremenu, korišćenjem i sufiksnog niza i LCP niza. To je dovoljno za obavljane linearne pretrage LCP kako bi se pronašla maksimalna vrednost akao i odgovarajući indeks na kome se nalazi . Najduži podniz koji se javlja najmanje dva puta je dat sa .

U nastavku su objašnjene dve aplikacije LCP niza: Kako se sufiksni niz i LCP niz mogu koristiti za izgradnju odgovarajućeg sufiksnog stabla i kako je moguće odgovoriti LCP upite za proizvoljne sufikse koji koriste minimalni raspon upita LCP niza.

Konstrukcija sufiksnog stabla[uredi | uredi izvor]

Dat nam je sufiksni niz i LCP niz od stringova dužine , njegogvo sufiksno stablo može se izgraditi u vremenu, na temelju sledeće ideje: Počnemo sa delimičnim sufiksnim stablom za leksikografski najmanji sufiks i zatim ubacujemo ostale sufikse po redosledu koji nam je dat sufiksnim nizom.

Neka je delimično sufiksno stablo za . Neka je dužina staze ulančavanja svih delova oznaka od korena do čvora .

Slučaj 1 (): Neka su dati sufiksi , , i niza već dodati u sufiksno stablo. Tada se sufiks dodaje kao što je prikazano na slici. Krajnji desni put je označen crvenom bojom.

Počnimo od , stabla koje se sastoji samo od korena. Za dodavanje u , prošetamo krajnje desnom putem sa početkom u nedavno dodatom listu pa do korena, sve dok se ne stigne do najdubljeg čvora sa je postignuto..

Moramo da razmotrimo sledeća dva sličaja:

  • : To znači da ulančavanje oznaka na putu od korena do čvora , je jednaka najdužem zajedničkom prefiksu sufiksa i .
    U tom slučaju, dodati kao novi list čvora i označiti rub sa . Tako se oznaka ruba sastoji od preostalih karaktera sufiksa koji nisu već zastupljeni u ulančavanju oznaka puta od korena do čvora path.
    Na ovaj način se gradi delimično sufiksno stablo .
    Slučaj 2 (): Da bi dodali sufiks , na rub prethodno ubačenog sufiks treba da se razdvoji. Novi rub internog čvora je označen sa najdužim zajedničkim prefiksom sufiksa i . Rub povezuje dva lista sa preostalim sufiksnim karakterima koji nisu deo prefiksa.
  • : To znači da ulančavanje oznaka na putu od korena do čvora prikazuje manje karaktera nego najduži zajednički prefiks sufiksa i i izgubljeni karakteri su sadržani u rubnoj oznaci od -tog najdesnijeg ruba. Tako da moramo razdvojiti taj rub na sledeći načins:
    Neka je potomak od u najdesnijem putu.
  1. Brisanje ruba .
  2. 2. Dodavanje novog internog čvora i novog ruba sa oznakom . Nova oznaka sastoji se od nestalih karaktera najdužeg zajedničkog prefiksa od i . Dakle, ulančavanje oznaka puta od korena do čvora sada pokazuje najduži zajednički prefiks od i .
  3. Spojiti na novonastali interni čvor od strane ruba koji je označen sa . Nova oznaka sastoji se od preostalih znakova brisanog ruba koji nisu korišćeni kao oznaka ruba .
  4. Dodati kao novi list i povezati ga sa novim internim čvorom od strane ruba koji je označen sa . Tako se oznaka ruba sastoji od preostalih karaktera sufiksa koji nisu već zastupljeni u ulančavanju oznaka puta od korena do čvora .
  5. Tako dobijamo delimično sufiksno stablo .

Jednostavna amortizacija argumenata pokazuje da je vreme rada ovog algoritma ograničeno sa :

Čvorovi koji su prelazili u koraku prošavši najdesnijim putem (osim poslednjeg čvora ) se uklanjaju iz najdesnijeg puta kada je dodan u stablo kao novi list. Ovim čvorovima se nikada više neće proći za sve naredne korake . Tako da će se gotovo uvek proći kroz čvorova, ukupno.

LCP upiti za proizvoljne sufikse[uredi | uredi izvor]

LCP niz sadrži samo dužinu najdužeg zajedničkog prefiksa svakog para sufiksa u sufiksnom nizu . Međutim, uz pomoć inverza sufiksnog niza (, tj. sufiksa koji počinje na poziciji u je pohranjen na položaju u ) i konstanto vreme raspona minimalnog upita na , moguće je odrediti dužinu najdužeg zajedničkog prefiksa proizvoljnih sufiksa u vremenu .

Zbog leksikografskog redosleda sufiksnog niza, svaki zajednički prefiks od sufiksa i mora biti zajednički prefiks svih sufiksa između -te pozicije u sufiksnom nizu i -te pozicije u sufiksnom nizu . Tako da, dužina najdužeg zajedničkog prefiksa koji deli sve ove sufikse je minimalna vrednost u intervalu . Ova vrednost može se naći u konstantnom vremenu, ako je predobrađen za raspon minimalnih upita.

Prema tome dobijen niz dužine i dve proizvoljne pozicije u stringu sa , dužina najdužeg zajedničkog prefiksa od sufiksa i može se izračunati na sledeći način: .

Reference[uredi | uredi izvor]

  1. ^ a b Abouelhoda, Kurtz & Ohlebusch 2004.
  2. ^ Manber & Myers 1993.
  3. ^ Crochemore & Ilie 2008.
  4. ^ Crochemore, Ilie & Smyth 2008.
  5. ^ Chen, Puglisi & Smyth 2008.

Spoljašnje veze[uredi | uredi izvor]