Saya ingin memfilter secara efisien daftar bilangan bulat untuk duplikat dengan cara yang hanya disimpan oleh set hasil.
Salah satu cara ini dapat dilihat:
- kami memiliki serangkaian bilangan bulat dengan besar (katakanlah )N 2 40
- kami memiliki fungsi dengan, konon, banyak tabrakan (gambar didistribusikan secara seragam dalam )S
- kita perlu menyimpan , yaitu{ f ( x ) | x ∈ S }
Saya memiliki estimasi (probabilistik) yang cukup akurat tentang apaadalah, dan karena itu dapat mengalokasikan struktur data di muka (katakan ).| f [ S ] | ≈ 2 30
Saya punya beberapa ide, tetapi saya tidak yakin apa yang akan menjadi pendekatan terbaik:
- bitet keluar dari pertanyaan karena set input tidak sesuai dengan memori.
- tabel hash, tetapi (1) membutuhkan beberapa overhead memori, katakanlah 150% daridan (2) tabel harus dieksplorasi ketika dibangun yang membutuhkan waktu tambahan karena overhead memori.
- semacam "on the fly", lebih disukai dengan kompleksitas (jenis non-perbandingan). Mengenai itu, saya tidak yakin apa perbedaan utama antara jenis ember dan flashsort .
- array sederhana dengan pohon pencarian biner, tetapi ini membutuhkan waktu .
- mungkin menggunakan filter Bloom atau struktur data serupa dapat berguna dalam relaksasi (dengan positif palsu) dari masalahnya.
Beberapa pertanyaan tentang stackoverflow tampaknya mengatasi hal-hal semacam ini ( /programming/12240997/sorting-array-in-on-run-time , /programming/3951547/java -array-Finding-duplikat ), tetapi tampaknya tidak ada yang cocok dengan persyaratan saya.
algorithms
data-structures
sorting
dokter
sumber
sumber
Jawaban:
Kenapa tidak bin dan rantai?
Idenya adalah untuk menyimpan bilangan bulat positif yang dapat direpresentasikan oleh bit dalam array dari entri yang mewakili rentang nilai: entri , , mewakili kisaran . Untuk setiap kita dapat menulis mana memiliki bit dan memiliki bit . Cobalah untuk menyimpan (bukan !) Di lokasi :A 2 k A [ y ] y ≥ 0 [ 2 m y , 2 m ( y + 1 ) - 1 ] 1 ≤ x < 2 n x = 2 m y + z y k z m z x yn=k+m A 2k A[y] y≥0 [2my,2m(y+1)−1] 1≤x<2n x=2my+z y k z m z x y
Ketika sudah, jangan lakukan apa-apa: adalah duplikat.xA[y]=z x
Ketika tidak diinisialisasi, simpan di .z A [ y ]A[y] z A[y]
Jika tidak, simpan indeks ke dalam array terpisah yang digunakan untuk rantai 's (yang bertabrakan pada ) dalam daftar tertaut. Anda harus mencari secara linear melalui daftar yang dikepalai oleh dan, tergantung pada apa yang ditemukan oleh pencarian, berpotensi memasukkan ke dalam daftar.y A [ y ] zz y A[y] z
Pada akhirnya, mudah untuk dipulihkan dengan memutar melalui entri yang diinisialisasi dari dan - dengan hanya menggabungkan dua bitstrings - memasang kembali setiap ditemukan di lokasi (baik secara langsung atau dalam rantai yang direferensikan di sana) ke aslinya nilai .A z y x = 2 m y + zf(S) A z y x=2my+z
Ketika distribusi mendekati seragam dan melebihi , tidak akan ada banyak rantai (ini dapat dinilai dengan cara biasa) dan rantai akan cenderung pendek. Ketika distribusinya tidak seragam, algoritme masih berfungsi, tetapi dapat mencapai waktu kuadratik. Jika itu suatu kemungkinan, gunakan sesuatu yang lebih efisien daripada rantai (dan bayar sedikit overhead untuk penyimpanan). N2k N
Penyimpanan yang dibutuhkan paling banyak adalah bit untuk dan bit untuk rantai (dengan asumsi ). Ini adalah persis ruang yang dibutuhkan untuk menyimpan nilai setiap bit. Jika Anda yakin dengan keseragaman, Anda dapat mengalokasikan simpanan yang kurang untuk rantai. Jika ketidakseragaman adalah suatu kemungkinan, Anda mungkin ingin meningkatkan dan menganjurkan penyimpanan rantai sepenuhnya. A 2 2 k m ≤ k 2 k n k2n A 22k m≤k 2k n k
Cara alternatif untuk memikirkan solusi ini adalah bahwa ia adalah tabel hash dengan fungsi hash yang sangat bagus (ambil bit yang paling signifikan) dan, karena itu, kita hanya perlu menyimpan bit paling tidak signifikan dalam tabel .m = n - kk m=n−k
Ada beberapa cara untuk overlay penyimpanan untuk rantai dengan penyimpanan untuk tetapi tampaknya tidak layak repot, karena itu tidak akan menghemat banyak (dengan asumsi jauh lebih kecil dari ) ruang dan akan membuat kode lebih sulit untuk dikembangkan, debug, dan pertahankan.m kA m k
sumber