Mai intai trebuie sa te autentifici.

Diferente pentru siruri-de-sufixe intre reviziile #10 si #11

Nu exista diferente intre titluri.

Diferente intre continut:

Sirul de sufixe se va gasi pe ultima linie a matricei $P$. Cautarea celui de-al $k$-lea sufix in ordine lexicografica este acum imediata, deci nu vom reveni asupra acestui aspect.
Cantitatea de memorie folosita poate fi redusa renuntand la folosirea intregii matrice $P$ si pastrindu-se la fiecare pas doar ultimele doua linii ale acesteia. In acest caz, insa, structura nu va mai fi capabila sa execute eficient operatia ce urmeaza.
 
h2. Calcularea celui mai lung prefix comun (LCP)
 
Se dau doua sufixe ale unui string $A$. Se cere calcularea celui mai lung prefix comun al lor. Am aratat ca un arbore de sufixe poate realiza aceasta in timp $O(1)$ cu o preprocesare corespunzatoare. Sa vedem daca un sir de sufixe poate atinge aceeasi performanta.
Fie cele doua sufixe $A{~i~}$ si $A{~j~}$. Folosind matricea $P$, putem itera descrescator de la cel mai mare $k$ pana la $0$ si verifica daca $A{~i~}^k^$ = $A{~j~}^k^$. Daca cele doua prefixe sunt egale, am gasit un prefix comun de lungime $2k$. Nu ne ramane decat sa actualizam $i$ si $j$, incrementandu-le cu $2k$ si sa verificam in continuare daca mai gasim prefixe comune.
Codul functiei care calculeaza _LCP_ este foarte simplu:
 
== code(cpp) |
int lcp(int x, int y)
{
    int k, ret = 0;
    if (x == y) return N - x;
    for (k = stp - 1; k >= 0 && x < N && y < N; k --)
        if (P[k][x] == P[k][y])
            x += 1 << k, y += 1 << k, ret += 1 << k;
    return ret;
}
==
 
Complexitatea este insa $O(lg n)$ pentru un calcul al acestui prefix. Reducerea la $O(1)$ se bazeaza pe urmatoarea observatie: $lcp(x, y)$ = $min{ lcp(x, x + 1), lcp(x + 1, x + 2), ..., lcp(y - 1, y) }$. Demonstratia este imediata daca ne uitam in arborele de sufixe corespunzator. Asadar, este suficient ca la inceput sa calculam cel mai lung prefix comun intre toate perechile de sufixe consecutive (timp $O(n lg n)$) si sa introducem o structura aditionala ce permite calculul in $O(1)$ al minimului dintr-un interval. Cea mai eficienta astfel de structura este cea pentru _RMQ_ (range minimum query), despre care nu vom da detalii aici, dar care este studiata in amanunt in [3], [4] si [5]. Cu inca o preprocesare in $O(n lg n)$ ceruta de noua structura putem acum sa raspundem in $O(1)$ query-urilor _LCP_. Structura folosita de _RMQ_ cere tot $O(n lg n)$ memorie, asadar timpul si memoria finale necesare sunt $O(n lg n)$.
 
h2. Cautarea
 
Deoarece sirul de sufixe ne ofera ordinea sufixelor lui $A$, cautarea unui string $W$ in $A$ se poate face simplu cu o cautare binara. Deoarece compararea se face in $O(|W|)$, cautarea va avea complexitatea $O(|W| lg n)$. Lucrarea [6] ofera structurii de date si algoritmului de cautare cateva rafinamente ce permit reducerea timpului la $O(|W| + lg n)$, dar autorii nu considera ca acestea sunt folositoare in concursurile de programare.

Nu exista diferente intre securitate.

Topicul de forum nu a fost schimbat.