Panduan untuk Teknik Lipat di Jawa

1. Pengenalan

Dalam tutorial ini, kami mempertimbangkan teknik hashing yang digunakan dalam pelbagai struktur data yang memberikan akses masa yang tetap ke elemennya.

Kami membincangkan dengan lebih terperinci apa yang disebut teknik lipatan dan memberikan pengenalan ringkas mengenai teknik mid-square dan binning.

2. Gambaran keseluruhan

Apabila kita memilih struktur data untuk menyimpan objek, salah satu pertimbangannya adalah sama ada kita perlu mengaksesnya dengan cepat.

Pakej utiliti Java menawarkan banyak struktur data untuk menyimpan objek kami. Untuk maklumat lebih lanjut mengenai struktur data, rujuk halaman kompilasi Koleksi Java kami yang berisi panduan tentang beberapa di antaranya.

Seperti yang kita ketahui, beberapa struktur data ini membolehkan kita mengambil unsur-unsurnya dalam masa yang tetap, tidak bergantung pada jumlah elemen yang terdapat di dalamnya.

Mungkin, yang paling mudah ialah susunan. Sebenarnya, kami mengakses elemen dalam array mengikut indeksnya. Masa akses, secara semula jadi, tidak bergantung pada ukuran susunan. Sebenarnya, di sebalik tabir, banyak struktur data banyak menggunakan tatasusunan.

Masalahnya adalah bahawa indeks array mesti berangka, sementara kita sering memilih untuk memanipulasi struktur data ini dengan objek.

Untuk mengatasi masalah ini, banyak struktur data berusaha memberikan nilai numerik yang dapat berfungsi sebagai indeks array untuk objek. Kami memanggil nilai ini sebagai nilai hash atau sekadar hash .

3. Mencambuk

Hashing adalah transformasi objek menjadi nilai berangka . Fungsi yang melakukan transformasi ini disebut fungsi hash .

Demi kesederhanaan, mari kita pertimbangkan fungsi hash yang mengubah rentetan menjadi indeks array, iaitu menjadi bilangan bulat dari julat [0, N] dengan N terhingga .

Secara semula jadi, fungsi hash diterapkan pada pelbagai rentetan . Oleh itu sifatnya "global" menjadi penting.

Sayangnya, tidak mustahil fungsi hash selalu mengubah rentetan yang berbeza menjadi nombor yang berbeza .

Kita boleh meyakinkan diri kita dengan mudah bahawa bilangan rentetan jauh lebih besar daripada bilangan bilangan bulat dalam julat mana pun [0, N] . Oleh itu, tidak dapat dielakkan terdapat sepasang rentetan tidak sama yang fungsi hash menghasilkan nilai yang sama. Fenomena ini disebut perlanggaran .

Kami tidak akan menyelidiki perincian kejuruteraan di sebalik fungsi hash, tetapi jelas bahawa fungsi hash yang baik harus berusaha memetakan seragam tali di mana ia ditakrifkan menjadi angka.

Keperluan lain yang jelas ialah fungsi hash yang baik harus cepat. Sekiranya terlalu lama untuk menghitung nilai hash, maka kita tidak dapat mengakses elemen dengan cepat.

Dalam tutorial ini, kami mempertimbangkan salah satu teknik yang cuba menjadikan pemetaan seragam sambil mengekalkannya dengan pantas.

4. Teknik Lipatan

Tujuan kami adalah untuk mencari fungsi yang mengubah rentetan menjadi indeks array. Hanya untuk menggambarkan idea, anggaplah bahawa kita mahu array ini mempunyai kapasiti untuk 105 elemen dan mari kita gunakan bahasa Java string sebagai contoh.

4.1. Penerangan

Mari mulakan dengan menukar watak rentetan menjadi nombor. ASCII adalah calon yang baik untuk operasi ini:

Sekarang, kami menyusun nombor yang baru kami peroleh ke dalam beberapa kumpulan ukuran. Secara amnya, kita memilih nilai ukuran kumpulan berdasarkan ukuran susunan kita iaitu 105. Oleh kerana nombor, di mana kita mengubah watak menjadi, terdiri dari dua hingga tiga digit, tanpa kehilangan umum, kita dapat menetapkan ukuran kumpulan menjadi dua:

Langkah seterusnya adalah menggabungkan nombor dalam setiap kumpulan seolah-olah mereka rentetan dan mencari jumlahnya:

Sekarang kita mesti membuat langkah terakhir. Mari kita periksa sama ada nombor 348933 dapat berfungsi sebagai indeks dari susunan ukuran 105 kita. Secara semula jadi, ia melebihi nilai maksimum yang dibenarkan 99999. Kita dapat dengan mudah mengatasi masalah ini dengan menggunakan operator modulo untuk mendapatkan hasil akhir:

348933 % 10000 = 48933

4.2. Ucapan Akhir

Kami melihat bahawa algoritma tidak termasuk operasi yang memakan masa dan oleh itu ia cukup pantas. Setiap watak rentetan input menyumbang kepada hasil akhir. Fakta ini pasti dapat membantu mengurangkan perlanggaran, tetapi tidak menghindarkannya sepenuhnya.

Sebagai contoh, jika kita mahu melangkau lipatan dan menggunakan operator modulo terus ke rentetan input yang diubah ASCII (mengabaikan masalah limpahan)

749711897321089711010311797103101 % 100000 = 3101

maka fungsi hash seperti itu akan menghasilkan nilai yang sama untuk semua rentetan yang mempunyai dua watak terakhir yang sama dengan rentetan input kami: ge , p age , lar ge, dan sebagainya.

Dari keterangan algoritma, kita dapat melihat dengan mudah bahawa ia tidak bebas dari perlanggaran. Contohnya, algoritma menghasilkan nilai hash yang sama untuk bahasa Java dan rentetan bahasa vaJa .

5. Teknik Lain

Teknik Lipat agak biasa, tetapi bukan satu-satunya. Kadang kala, teknik binning atau mid-square mungkin berguna juga.

Kami menggambarkan idea mereka dengan tidak menggunakan rentetan, tetapi angka (anggaplah kita telah mengubah rentetan menjadi angka). Kami tidak akan membincangkan kelebihan dan kekurangan mereka, tetapi anda mungkin akan mengeluarkan pendapat setelah melihat algoritma.

5.1. Teknik Binning

Anggaplah kita mempunyai 100 nombor bulat dan kita mahu fungsi hash kita memetakannya menjadi pelbagai 10 elemen. Kemudian kita boleh mengatur 100 bilangan bulat itu menjadi sepuluh kumpulan sedemikian rupa sehingga sepuluh bilangan bulat pertama berakhir di tong pertama, sepuluh bilangan bulat kedua berakhir di tong kedua, dan lain-lain:

5.2. Teknik Mid-Square

Algoritma ini dicadangkan oleh John von Neumann dan ia membolehkan kita menghasilkan nombor pseudo-random bermula dari nombor yang diberikan.

Mari kita gambarkan pada contoh konkrit. Katakan, kita mempunyai nombor empat digit 1111 . Menurut algoritma, kami menjulurkannya , sehingga memperoleh 1234321 . Sekarang, kami mengeluarkan empat digit dari tengah, misalnya, 2343 . Algoritma ini membolehkan kita mengulangi proses ini sehingga kita berpuas hati dengan hasilnya.

6. Kesimpulannya

Dalam tutorial ini, kami mempertimbangkan beberapa teknik hashing. Kami menerangkan secara terperinci teknik melipat dan memberikan penerangan kilat tentang bagaimana binning dan mid-square dapat dicapai.

Seperti biasa, kami mungkin menemui coretan kod yang sesuai di repositori GitHub kami.