LCP низ
Овај чланак је започет или проширен кроз пројекат семинарских радова. Потребно је проверити превод, правопис и вики-синтаксу. Када завршите са провером, допишете да након |проверено=. |
LCP низ | ||
---|---|---|
Тип | низ | |
Проналазач | Manber & Myers 1990 | |
Временска и просторна сложеност у велико О нотацији | ||
Просечан случај | Најгори случај | |
Простор | ||
Време |
У информатици, најдужи заједнички префикс низ (енг. longest common prefix array) је помоћна структура података при суфиксном низу. Она чува дужине најдужих заједничких префикса, између парова узастопних суфикса у сортираном суфиксном низа. Другим речима, то је дужина префикса заједничка за два узастопна суфикса у сортираном низу суфикса.
Пример:
LCP од a и aabba је 1.
LCP од abaabba и abba је 2.
Повећавајући суфиксни низ са LCP низом омогућава ефикасно симулирање одозго надоле и одоздо нагоре обилазак стабла за суфиксно стабло, образац поклапања код суфиксног низа и предуслов је за компримовано суфиксно стабло.
Историја
[уреди | уреди извор]LCP низ су заједно са суфиксним низом увели, 1993. године, Udi Manber и Gene Myers са циљем да побољшају временску сложеност алогоритма претраге низа стрингова. Gene Myers је бивши потпредседник Informatics Research у Celera Genomics, а Udi Manber је био потпредседник инжењеринг у Google.
Дефиниција
[уреди | уреди извор]Нека је суфиксни низ низа стрингова и нека означава дужину најдужег заједничког прфикса између два стринга и . Означимо додатно са подниз од у распону од до .
Тада је LCP низ цео низ дужине, тако да је недефинисан и за свако . Тако да чува дужину најдужег заједничког префикса од лексикографски и-тог најмањег заједничког суфикса и његов претходник у низу суфикса.
Пример
[уреди | уреди извор]Размотримо стринг :
i | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
S[i] | b | a | n | a | n | a | $ |
и одговарајући суфиксни низ :
i | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
A[i] | 7 | 6 | 4 | 2 | 1 | 5 | 3 |
Комплетан суфиксни низ са самим суфиксом :
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 | $ |
Тада је LCP низ конструисан поређењем лексикографски узастопних суфикса да би се утврдио њихов најдужи заједнички префикс:
i | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
H[i] | 0 | 1 | 3 | 0 | 0 | 2 |
Нпр., је дужина најдужег заједничког префикса подељена суфиксима и . Треба имати у виду да је , докле год нема лексикографски мањег суфикса.
Разлика између суфиксног низа и LCP низа
[уреди | уреди извор]Суфиксни низ: Представља лексикографкс ранг сваког суфикса низа.
LCP низ: Садржи максималну дужина префикса који се поклапа између два узастопна суфикса, након што су сортирани лексикографски.
Употреба LCP низа у проналажењу број појава обрасца
[уреди | уреди извор]У циљу налажења број појављивања датог стринг P (дужина m) у тексту Т (дужине N),
- Мора се користити бинарна претрага за суфикс дужине Т.
- Требало би се убрзати применом LCP низа као помоћне структуре података. Прецизније, требало би направити посебну верзију LCP низа (LCP-LR низ) и користити такав низ.
Проблем са коришћењем стандардне бинарне претраге (без LCP низа) је да се у сваком од O(log N) поређења која су потребна да би упоредили P важећим улазним суфиксом низа, пролазимо м карактера. Дакле, сложеност је O(m*log N).
LCP-LR низ побољшава сложеност до O(m+log N), на следећи начин:
У било ком тренутку током бинарне претраге, ви сматрате, као и обично, низ (L,...,R)суфиксом низа и његова централна тачка М, одлучите да ли наставити претрагу у левом поднизу (L,...,M) или у десном поднизу (M,...,R). Да би донели одлуку, упоредите P са стрингом у М. Ако је P идентичан М, готово, али ако није, имаћете у односу на првих K карактера P а затим одлучити да ли је P лексикографски мање или већа од М. Претпоставимо исход је да је P већи од М. Дакле, у следећем кораку, ви сматрате (M,...,R) и нова централна тачка M' у средини:
M ...... M' ...... R | знамо: lcp(P,M)==k
Трик је у томе да је LCP-LR унапред одређено као што О(1) -указује на најдужи заједнички префикс М и M', lcp(M,M').
Већ из претходног корака знамо lcp(P,M)=k.да и сам М има префикс заједничких ликова са P. Сада постоје три могућности:
- Случај 1: k < lcp(M,M'), тј. Р има мање префиксних карактера заједничких са М него што има М са М'. Ово значи (k+1)-ви карактер M' је исти као код М, а пошто P лексикографски већа од М, онда мора бити лексикографски веће и од М'. Тако смо и даље у десној половини (M',...,R).
- Случај 2: k > lcp(M,M'), тј. P има више префиксних карактера заједничких са М него М са М'. Према томе, ако смо за поређење P на М', заједничких префикса, мање од К и М' биће лексикографски већа од p, тако, без упоређења, настављамо у левој половини (M,...,M').
- Случај 3: k == lcp(M,M'). Тако ако су М и М' оба идентични са P у првих к карактера. Да би се одлучило да ли ћемо наставити са леве или десне стране, довољно је упоредити P на М', почевши од (k+1)-ог карактера.
- Наставити рекурзивно.
Свеукупни учинак је да се ниједан карактер p не пореди са било којим карактером из текста више од једног пута. Укупан број поређења карактера је ограничен м, тако да је укупна сложеност заиста О(m+log n).
Очигледно, преостало је још кључно питање како смо одредили LCP-LR тако да нам сложеност LCP-a између било која два уписа у суфиксном низу буде О(1)? Као што је речено, стандардни LCP низ говори нам само да имамо LCP узастопних улазака, односно LCP (x-1, x) за било које x. Ма да, M i M' у опису изнад нису кључно узастопни улази, па како смо онда то учинили?
Кључно за то је да схватимо да се одређени распони (L,...,R) никада неће појавити током бинарне претраге: она увек почиње са (0,...,n) и дели на средини, а затим даље било лево или десно и онда опет подели ту половину. Ако размишљамо о томе: сваки улазак суфиксом низ настаје као централна тачка тачно једног могућег распона током бинарне претраге. Дакле, постоји тачно n различитих распона (L...M...R) који евентуално могу играти улогу у бинарном претраживању, а довољно је одредити lcp(L,M) и lcp(M,R) за оних N могућих распона. Тако да имамо 2*N различитих, унапред израчунатих вредности, па је LCP-LR сложености O(N).
Осим тога, ту је једноставан алгоритам за одређивање 2xN вредности LCP-LR у времену O(N) за стандардне LCP низове.
Да сумирамо:
- Могуће је израчунати LCP-LR у времену O(N) и O(2*N)=O(N) простору за LCP.
- Коришћење LCP-LR током бинарне претраге убрзава поступак са O(M*log N) to O(M+log N).
- Могу се користити две бинарне претраге да би се одредио леви и десни крај опсега за подударање P, а даљи опсег подударања одговара броју појављивања за P.
Ефикасна конструкција алгоритма
[уреди | уреди извор]Алгоритми за конструкцију LCP низа могу се поделити на две категорије: алгоритми који израчунавају LCP низ као нуспродукт у суфиксном низу и алгоритми који користе већ изграђени суфиксни низ како би израчунали LCP вредности.
Manber & Myers 1993 ају алгоритам за рачунање LCP низа уз суфиксни низ у времену. Kärkkäinen & Sanders 2003 показују да је могуће модификовати њихово време алгоритма, а да при том једнако добро израчунава LCP низ. Kasai et al. 2001 представљају први алгоритам у времену, алгоритам (FLAAP), који израчунава LCP низ у односу на текст и суфиксни низ. Под претпоставком да је сваки текстуални симбол величине једног бајта и сваки улазак у суфиксни или LCP низ траје 4 бајта, главни недостатак њиховог алгоритма је то што је попуњен велики простор бајтова, док изворни излаз (текст, суфиксни или LCP низ) заузима само бајтова. Тако да је Manzini 2004 аправио бољу верзију алгоритма Kasai et al. 2001 (lcp9) и са којим је смањио количину попуњеног простора за бајтова. Kärkkäinen, Manzini & Puglisi 2009 дају један још бољи Kasai's алгоритам (-алгоритам) који побољшава потребно време. Уместо стварног LCP низа, овај алгоритам гради пермутовани LCP (PLCP) низ, у којем су вредности које се појављују у тексту у лексикографском поретку. Gog & Ohlebusch 2011 дају два алгоритма, који иако су спори у теорији (), у пракси су доста бржи.
Од 2012. године, тренутно најбржи, линеарног времена, алгоритма за конструкцију LCP низа је Fischer 2011 , који се темељи на једном од најбржих алгоритама за конструкцију суфиксног низа Nong, Zhang & Chan 2009 .
Апликације
[уреди | уреди извор]Као што је наведено од стране Abouelhoda, Kurtz & Ohlebusch 2004 неколико проблема се може решити употребом следећих врста обилазака стабла:
- одоздо према горе обухватањем целокупног суфиксног стабла
- одозго према доле обилазак подстабла суфиксног стабла
- Обилазак суфиксног стабла помоћу суфиксних линкова.
Kasai et al. 2001 показују како симулирати одоздо према горе обилазак суфиксног стабла, коришћењем само суфиксног и LCP низа. Abouelhoda, Kurtz & Ohlebusch 2004 су побољшали суфиксни низ са LCP низом и додатном структуром података, и описали како се побољшани суфиксни низ може користити за симулацију сва три обиласка суфиксног стабла. Fischer & Heun 2007 смањује захтеве за простором од стране побољшаног суфиксног низа са предизрачунатим LCP низом за распон минималних упита . Дакле, сваки проблем који се може режити алгоритмом за суфиксно стабло, може се решити и са побољшаним суфиксним стаблом. [1]
Одлучивање, ако је узорак дужине подниза стрингова дужине траје времена, ако се користи само суфиксни низ. Додатно коришћењем LCP, ово може бити побољшано на .[2] Abouelhoda, Kurtz & Ohlebusch 2004 показују како побољшати ово време и даље како би се постигла оптимална сложеност time. Дакле, помоћу суфиксног низа i LCP низа, одабрани упити може одговарати једнако брзо као и применом суфиксног стабла.
LCP низ је битан део компримованих суфиксних стабала који пружа пуну функционалност суфиксним стаблима као суфиксних линкова и најважнијег заједничког претка упита. Осим тога може се користити заједно са суфиксним низом за израчунавање Lempel-Ziv LZ77 факторизације у времену. [1][3][4][5]
Проблем најдуже понављаног подниза за низ дужине може бити решен у времену, коришћењем и суфиксног низа и LCP низа. То је довољно за обављане линеарне претраге LCP како би се пронашла максимална вредност акао и одговарајући индекс на коме се налази . Најдужи подниз који се јавља најмање два пута је дат са .
У наставку су објашњене две апликације LCP низа: Како се суфиксни низ и LCP низ могу користити за изградњу одговарајућег суфиксног стабла и како је могуће одговорити LCP упите за произвољне суфиксе који користе минимални распон упита LCP низа.
Конструкција суфиксног стабла
[уреди | уреди извор]Дат нам је суфиксни низ и LCP низ од стрингова дужине , његогво суфиксно стабло може се изградити у времену, на темељу следеће идеје: Почнемо са делимичним суфиксним стаблом за лексикографски најмањи суфикс и затим убацујемо остале суфиксе по редоследу који нам је дат суфиксним низом.
Нека је делимично суфиксно стабло за . Нека је дужина стазе уланчавања свих делова ознака од корена до чвора .
Почнимо од , стабла које се састоји само од корена. За додавање у , прошетамо крајње десном путем са почетком у недавно додатом листу па до корена, све док се не стигне до најдубљег чвора са је постигнуто..
Морамо да размотримо следећа два сличаја:
- : То значи да уланчавање ознака на путу од корена до чвора , је једнака најдужем заједничком префиксу суфикса и .
У том случају, додати као нови лист чвора и означити руб са . Тако се ознака руба састоји од преосталих карактера суфикса који нису већ заступљени у уланчавању ознака пута од корена до чвора path.
На овај начин се гради делимично суфиксно стабло . - : То значи да уланчавање ознака на путу од корена до чвора приказује мање карактера него најдужи заједнички префикс суфикса и и изгубљени карактери су садржани у рубној ознаци од -тог најдеснијег руба. Тако да морамо раздвојити тај руб на следећи начинs:
Нека је потомак од у најдеснијем путу.
- Брисање руба .
- 2. Додавање новог интерног чвора и новог руба са ознаком . Нова ознака састоји се од несталих карактера најдужег заједничког префикса од и . Дакле, уланчавање ознака пута од корена до чвора сада показује најдужи заједнички префикс од и .
- Спојити на новонастали интерни чвор од стране руба који је означен са . Нова ознака састоји се од преосталих знакова брисаног руба који нису коришћени као ознака руба .
- Додати као нови лист и повезати га са новим интерним чвором од стране руба који је означен са . Тако се ознака руба састоји од преосталих карактера суфикса који нису већ заступљени у уланчавању ознака пута од корена до чвора .
- Тако добијамо делимично суфиксно стабло .
Једноставна амортизација аргумената показује да је време рада овог алгоритма ограничено са :
Чворови који су прелазили у кораку прошавши најдеснијим путем (осим последњег чвора ) се уклањају из најдеснијег пута када је додан у стабло као нови лист. Овим чворовима се никада више неће проћи за све наредне кораке . Тако да ће се готово увек проћи кроз чворова, укупно.
LCP упити за произвољне суфиксе
[уреди | уреди извор]LCP низ садржи само дужину најдужег заједничког префикса сваког пара суфикса у суфиксном низу . Међутим, уз помоћ инверза суфиксног низа (, тј. суфикса који почиње на позицији у је похрањен на положају у ) и константо време распона минималног упита на , могуће је одредити дужину најдужег заједничког префикса произвољних суфикса у времену .
Због лексикографског редоследа суфиксног низа, сваки заједнички префикс од суфикса и мора бити заједнички префикс свих суфикса између -те позиције у суфиксном низу и -те позиције у суфиксном низу . Тако да, дужина најдужег заједничког префикса који дели све ове суфиксе је минимална вредност у интервалу . Ова вредност може се наћи у константном времену, ако је предобрађен за распон минималних упита.
Према томе добијен низ дужине и две произвољне позиције у стрингу са , дужина најдужег заједничког префикса од суфикса и може се израчунати на следећи начин: .
Референце
[уреди | уреди извор]Спољашње везе
[уреди | уреди извор]- Mirror of the ad-hoc-implementation of the code described in Fischer 2011
- SDSL: Succinct Data Structure Library - Provides various LCP array implementations, Range Minimum Query (RMQ) support structures and many more succinct data structures
- Bottom-up suffix tree traversal emulated using suffix array and LCP array (Java)
- Text-Indexing project (linear-time construction of suffix trees, suffix arrays, LCP array and Burrows-Wheeler Transform)