Hashing Stringova

Embed Size (px)

Citation preview

  • 7/23/2019 Hashing Stringova

    1/4

    Hashing stringova

    Od svega sto se moze susresti na natjecanjima stringovi su uvjerljivo najcesce zrtve hashiranja.Usporedbe stringova znak po znak nisu uvijek dovoljno efikasne, pa cemo zato sada prouc iti jednuvrlo popularnu metodu hashiranjastringova koja dozvoljava brzo izdvajanje pojedinih podstringova (tj.

    dobivanje njihovih hashvrijednosti). Takoer cemo vidjeti vrlo efikasan nac in leksikografskogusporeivanja podstringova.

    Hash funkcija za stringove

    Hash funkcija koju obicno koristimo za stringove takoer ima oblik polinoma, gdje su koeficijentiznakovi samog stringa. Vrijednosti cemo pohranjivati u intove, ovaj puta bez direktnog racunanjanekog ostatka (za to ce se pobrinuti sama implementacija tipa podatka int , odnosno njegov

    overflow).

    Nazovimo string s kojim radimo

    Niz

    polinoma u nekoj tocki. Isti taj niz zato mozemo zapisati u nesto preglednijem obliku:

    Kao hashvrijednost zadanog stringa podrazumijevamo , a ostale c lanove niza nazivamoprefiks hashevima. Ovdje emo josnapomenuti kako za samu hash vrijednost

    vrijednost pripadajuceg znaka. Takoer necemo brinuti o overflow problemima koji bi eventualnonastali i jednostavno cemo ih ignorirati. Mozete se uvjeriti kako se sve operacije u tom slucaju slicne

    onima modulo

    Sljedeci korak je izdvajanje hashvrijednosti podstringova stringa S. Oznac imo sa podstring

    stringa

    Zacudo tu vrijednost mozemo jednostavno dobiti iz vecizracunatog pomocnog niza

    Sljedeca formula daje nam tu poveznicu:

    Ideja kojom dolazimo do te formule je ta da prvo uzmemo prefiks i tada od njega jednostavno

    , njegovu duljinu i odaberimo prosti broj . Pomocne nizove i

    definiramo rekurzivno na sljedeci nac in:

    je niz potencija broja (po nekom modulu, obino uz overflow). No sto nam predstavlja niz ?Izgleda kao da ima veze s polinomima, preciznije jako je slican Hornerovom algoritmu za evaluiranje

    ovdje uzimamo

    .

    koji se provlac i od znaka

    sljedecu sumu:

    do znaka . Po nasoj definiciji hash vrijednosti stringa dobivamo

    .

    Hashing stringova

    1

  • 7/23/2019 Hashing Stringova

    2/4

    odrezemo prefiks . Kako je znak

    implementaciji ove formule naravno moramo paziti na to da ne gledamo negativne indekse.

    Sada vecposjedujemo puno alata i bacamo se na neke jednostavnije primjene.

    Traenje malog string u veemPretpostavimo da imamo dva stringatraz imo i pomocne nizovestring

    indekse

    Ova ideja c ini osnovu Rabin-Karpalgoritma za trazenje patterna. Primijetite i da je ovo moguce izvestii bez pomocnih nizova za string

    Kako bismo bili potpuno sigurni da nemamo slucaj kolizije potrebno je i rucno provjeriti svaki podstringkoji se pokaze jednak po hash vrijednosti, no to ce se uz zadanu hash funkciju dogaati vrlo rijetko.Zbog toga se cak mozemo praviti da hash vrijednost predstavlja sam string.

    Slican princip mozemo primijeniti na visedimenzionalne nizove. U 2dslucaju mozemo na primjer prvoizracunati hash vrijednosti stupaca (i njihovih podstringova), i zatim te podstringove promatrati kaojednodimenzionalne nizove. Takoer mozemo lako prebrojavati podstringove odreene fiksne duljine ijosmnogo toga.

    Palindrom i periodinostiPalindromi su josjedan primjer gdje hashing moze dobro doci. Ako umijesto samo jednog pomocnog

    niza kao niz prefiks hasheva obrnutog stringa. Oznac imo obrnuti string

    palindrom svodi na ispitivanje jednakosti

    .

    Periodicnost stringa takoer je jednostavna za provjeriti, uzmemo svaki prefiks stringa, pomicemo seza njegovu duljinu i pritom testiramo jednakost. Buduci da duljina mora biti djeljiva duljinom periodabroj pocetnih prefiksa je prilicno ogranicen.

    Najdulji zajedniki prefiks

    Najdulji zajednicki prefiks (engl. longest common prefix, LCP) dvaju stringova definira se kao najduljiprefiks prvog stringa koji je ujedno i prefiks drugog stringa. Rubni slucaj je naravno onaj u kojem jejedan od stringova prefiks drugoga. Trazenje LCP-a moze se vrlo efikasno izvesti koristenjem vec opisane hash funkcije i binarnog pretraz ivanja. Uistinu ako je stringprefiks stringa

    Tada bi odsjeak za racunanje duljine njihovog LCP-a isao otprilike ovako:

    u odnosu na znak na potenciji visoj za

    odgovara duljini podstringa), taj drugi prefiks potrebno je pomnoz iti s . Pri konkretnoj

    (sto

    i s duljinama redom i , i neka je manje od tj.u . Za pocetak izracunamo hash vrijednost stringa - i za

    za sve odgovarajuce. Tada se ovo trazenje svodi na ispitivanje je li jednak

    (ima ih ).

    ako pri pomicanju na sljedeci indeks odrzavamo vrijednosthash vrijednost trenutno promatranog podstringa. Tada pomocu nizatrenutnog hasha i dodajemo novi znak na kraj.

    kaoizbacujemo prvi znak iz

    konstruiramo i niz sa

    . Tada ispitivanje je li podstring i

    prefiks stringa tada je svakitakoer prefiks stringai

    . Pretpostavimo da su nam zadana dva podstringa stringa, redom .

    Hashing stringova

    2

  • 7/23/2019 Hashing Stringova

    3/4

    intLCP(int x0,int y0,int x1,int y1) {

    if(S[x0] !=S[x1]) {

    return0;

    }

    int lo=1,hi=std::min(y0-x0+1,y1-x1+1);

    while(lo

  • 7/23/2019 Hashing Stringova

    4/4

    http://www.spoj.pl/problems/HSEQ/

    http://www.spoj.pl/problems/LSQF/

    http://www.spoj.pl/problems/DISUBSTR/

    HintoviTREEISO: Postoji cvor (ili dva) u stablu koji se nazivaju centar i jedinstveni su svakom stablu.Obilazak stabla iz nekog od ta dva cvora moze se zapisati u niz. (Taj niz opet treba biti paz ljivoizgraen buduci da redoslijed cvorova u listi koju koristimo za obilazak nije nuzno isti u obastabla). Zbog slabijih primjera moguce je i da neke druge heuristike takoer prolaze.

    HSEQ: Osnovni hint je suffix array odnosno niz sortiranih sufiksa stringa. Potrebno je promatratiLCPsusjednih sufiksa u tom nizu. Uz malo promatranja lako je prepoznati problem najvecegpravokutnika u histogramu (mozete pogledati i zadatak http://www.spoj.pl/problems/HISTOGRA/).

    LSQF: Postoji nac in provjeravanja postoji li takav string duljine

    algoritam promatra prvih

    common suffix

    duljine. Rjesenje se dobije prolaskom po svim mogucim ki slozenosti je

    DISUBSTR: Za kraj jedan suffix array zadatak. Opet je potrebno sortirati sufikse i promatratiuzastopne LCP-ove. Ideja je od ukupnog broja substringova oduzeti ponavljanja. Lako je vidjetikako LCP dva susjedna sufiksa duljine

    2014. Gustav Matula, Matija antl

    Ovaj lanak objavljen je podCreative Commons Attribution-ShareAlike 3.0 Croatia License

    za bilokoji u . Taj

    , drugih itd. uzastopnih znakova i koristeci LCPi LCS(longest

    koji se racuna gotovo isto kao LCP) traz i postoji li opisani podstring upravo te

    .

    predstavlja tocno ponovljenih substringova.

    Hashing stringova

    4