Vodič za tehniku ​​presavijanja u Javi

1. Uvod

U ovom uputstvu razmatramo tehnike raspršivanja koje se koriste u različitim strukturama podataka koje pružaju stalan vremenski pristup njihovim elementima.

Detaljnije raspravljamo o tzv tehnika presavijanja i dati kratki uvod u tehnike srednjeg kvadrata i binning tehnike.

2. Pregled

Kada odaberemo strukture podataka za spremanje objekata, jedno od razmatranja je treba li im brzo pristupiti.

Paket uslužnih programa Java nudi nam dosta podatkovnih struktura za pohranu naših objekata. Dodatne informacije o strukturama podataka potražite na našoj stranici za kompilaciju zbirki Java koja sadrži vodiče za nekoliko njih.

Kao što znamo, neke od ovih struktura podataka omogućuju nam da dohvatimo njihove elemente u stalnom vremenu, neovisno o broju elemenata koje sadrže.

Vjerojatno je najjednostavniji niz. Zapravo, elementima u nizu pristupamo prema njihovom indeksu. Vrijeme pristupa, naravno, ne ovisi o veličini polja. U stvari, iza scene mnoge strukture podataka intenzivno koriste nizove.

Problem je u tome što indeksi nizova moraju biti numerički, dok tim strukturama podataka često radije manipuliramo objektima.

Da bi se riješili ovaj problem, mnoge podatkovne strukture pokušavaju dodijeliti numeričku vrijednost koja objektima može poslužiti kao indeks niza. Ovu vrijednost nazivamo a hash vrijednost ili jednostavno a hash.

3. raspršivanje

Hashing je transformacija objekta u numeričku vrijednost. Pozvane su funkcije koje izvode ove transformacije hash funkcije.

Radi jednostavnosti, razmotrimo hash funkcije koje transformiraju nizove u indekse nizova, odnosno u cijele brojeve iz raspona [0, N] s konačnim N.

Prirodno, hash funkcija se primjenjuje na širok spektar žica. Stoga njegova "globalna" svojstva postaju važna.

Nažalost, nije moguće da hash funkcija uvijek transformira različite nizove u različite brojeve.

Možemo se prilično lako uvjeriti da je broj nizova puno veći od broja cijelih brojeva u bilo kojem rasponu [0, N]. Stoga je neizbježno da postoji par nejednakih nizova za koje hash funkcija daje jednake vrijednosti. Taj se fenomen naziva sudar.

Nećemo zalaziti u inženjerske detalje iza hash funkcija, ali jasno je da bi dobra hash funkcija trebala pokušati jednoliko mapirati nizove na kojima je definirana u brojeve.

Sljedeći je očiti zahtjev da dobra hash funkcija treba biti brza. Ako je izračunavanje hash vrijednosti predugo, tada ne možemo brzo pristupiti elementima.

U ovom uputstvu razmatramo jedan od tehnike kojima se pokušava mapiranje ujednačiti održavajući ga brzo.

4. Tehnika presavijanja

Cilj nam je pronaći funkciju koja transformira žice u indekse nizova. Samo da ilustriramo ideju, pretpostavimo da želimo da ovaj niz ima kapacitet za 105 elemenata i upotrijebimo string Java jezik kao primjer.

4.1. Opis

Počnimo s pretvaranjem znakova niza u brojeve. ASCII je dobar kandidat za ovu operaciju:

Sada brojeve koje smo upravo dobili rasporedimo u grupe neke veličine. Općenito, vrijednost veličine grupe biramo na temelju veličine našeg polja koja je 105. Budući da brojevi, u koje smo transformirali znakove, sadrže dvije do tri znamenke, bez gubitka općenitosti, veličinu grupe možemo postaviti na dva:

Sljedeći je korak spajanje brojeva u svakoj grupi kao da su nizovi i pronalazak njihovog zbroja:

Sada moramo napraviti posljednji korak. Provjerimo je li broj 348933 može poslužiti kao indeks našeg niza veličine 105. Naravno, premašuje maksimalnu dopuštenu vrijednost 99999. Ovaj problem možemo lako prevladati primjenom modulo operatora kako bismo pronašli konačni rezultat:

348933 % 10000 = 48933

4.2. Završne napomene

Vidimo da algoritam ne uključuje radnje koje oduzimaju puno vremena i stoga je prilično brz. Svaki znak ulaznog niza doprinosi konačnom rezultatu. Ova činjenica definitivno pomaže smanjiti sudare, ali ne i potpuno ih izbjeći.

Na primjer, ako smo htjeli preskočiti presavijanje i primijenili modulo operator izravno na ASCII transformirani ulazni niz (zanemarujući problem preljeva)

749711897321089711010311797103101 % 100000 = 3101

tada bi takva hash funkcija stvorila istu vrijednost za sve nizove koji imaju ista posljednja dva znaka kao i naš ulazni niz: agestrdob, large, i tako dalje.

Iz opisa algoritma lako možemo vidjeti da nije slobodan od sudara. Na primjer, algoritam daje istu raspršenu vrijednost za Java jezik i vaJa jezik žice.

5. Ostale tehnike

Tehnika presavijanja prilično je česta, ali ne i jedina. Ponekad, binning ili sredinom kvadrata tehnike također mogu biti korisne.

Njihovu ideju ilustriramo ne koristeći nizove, već brojeve (pretpostavimo da smo već nekako transformirali nizove u brojeve). Nećemo razgovarati o njihovim prednostima i slabostima, ali možda ćete stvoriti mišljenje nakon što vidite algoritme.

5.1. Tehnika spajanja

Pretpostavimo da imamo 100 cjelobrojnih brojeva i želimo da ih naša hash funkcija preslika u niz od 10 elemenata. Tada možemo jednostavno rasporediti tih 100 cijelih brojeva u deset skupina na takav način da prvih deset cijelih brojeva završi u prvom spremniku, a drugih deset cijelih brojeva završi u drugom spremniku itd.:

5.2. Tehnika srednjeg kvadrata

Ovaj algoritam predložio je John von Neumann i on nam omogućuje generiranje pseudo-slučajnih brojeva počevši od određenog broja.

Ilustrirajmo to na konkretnom primjeru. Pretpostavimo da imamo četveroznamenkasti broj 1111. Prema algoritmu, kvadriramo ga, dobivajući tako 1234321‬. Sada iz sredine izdvajamo četiri znamenke, na primjer, 2343. Algoritam nam omogućuje ponavljanje ovog postupka dok ne budemo zadovoljni rezultatom.

6. Zaključak

U ovom smo tutorijalu razmotrili nekoliko tehnika raspršivanja. Detaljno smo opisali tehniku ​​presavijanja i kratko opisali kako se može postići spajanje i srednji kvadrat.

Kao i uvijek, možda ćemo pronaći odgovarajuće isječke koda na našem GitHub spremištu.