Aku punya dua set besar bilangan bulat dan . Setiap set memiliki sekitar satu juta entri, dan setiap entri adalah bilangan bulat positif dengan panjang maksimal 10 digit.
Apa algoritma terbaik untuk menghitung dan ? Dengan kata lain, bagaimana saya bisa secara efisien menghitung daftar entri yang tidak dalam dan sebaliknya? Apa yang akan menjadi struktur data terbaik untuk mewakili dua set ini, untuk membuat operasi ini efisien?
Pendekatan terbaik yang bisa saya lakukan adalah menyimpan dua set ini sebagai daftar yang diurutkan, dan membandingkan setiap elemen terhadap setiap elemen , secara linear. Bisakah kita berbuat lebih baik?
algorithms
data-structures
sets
pengguna917279
sumber
sumber
Jawaban:
Jika Anda ingin menyimpan set dalam struktur data khusus, maka Anda mungkin bisa mendapatkan beberapa kompleksitas yang menarik.
Kemudian Anda dapat melakukan operasi set dan , masing-masing di perkiraan waktu. Jadi pada dasarnya, Anda mendapatkan ukuran minimum dari dua set, atau, ukuran perbedaan simetris, mana yang lebih kecil. Ini lebih baik daripada linear, jika perbedaan simetris kecil; yaitu. jika mereka memiliki persimpangan besar. Bahkan, untuk dua operasi set-perbedaan yang Anda inginkan, ini praktis peka-output, karena bersama-sama mereka membuat ukuran perbedaan simetris.A∪B,A∩B,A∖B AΔB O(I⋅log|A|+|B|I)
Lihat Confluently Persistent Sets and Maps oleh Olle Liljenzin (2013) untuk informasi lebih lanjut.
sumber
Pemindaian linier adalah yang terbaik yang saya tahu bagaimana melakukannya, jika set diwakili sebagai daftar tertaut yang diurutkan. Waktu berjalan adalah .O(|A|+|B|)
Perhatikan bahwa Anda tidak perlu membandingkan setiap elemen terhadap setiap elemen B , berpasangan. Itu akan menyebabkan runtime O ( | A | × | B | ) , yang jauh lebih buruk. Sebagai gantinya, untuk menghitung perbedaan simetris dari dua set ini, Anda dapat menggunakan teknik yang mirip dengan operasi "penggabungan" di mergesort, yang dimodifikasi untuk menghilangkan nilai-nilai yang umum untuk kedua set.A B O(|A|×|B|)
Secara lebih rinci, Anda dapat membangun algoritme rekursif seperti berikut untuk menghitung , dengan asumsi A dan B direpresentasikan sebagai daftar tertaut dengan nilainya dalam urutan:A∖B A B
Saya sudah mewakili ini dalam pseudo-Python. Jika Anda tidak membaca Python,
A[0]
adalah kepala dari daftar yang ditautkanA
,A[1:]
adalah sisa dari daftar, dan+
mewakili gabungan daftar. Untuk alasan efisiensi, jika Anda bekerja dengan Python, Anda mungkin tidak ingin mengimplementasikannya persis seperti di atas - misalnya, mungkin lebih baik menggunakan generator, untuk menghindari membangun banyak daftar sementara - tetapi saya ingin menunjukkan kepada Anda ide-ide dalam bentuk sesederhana mungkin. Tujuan dari pseudo-code ini hanya untuk menggambarkan algoritma, bukan mengusulkan implementasi konkret.Saya tidak berpikir itu mungkin untuk melakukan yang lebih baik, jika set Anda direpresentasikan sebagai daftar yang diurutkan dan Anda ingin hasilnya disediakan sebagai daftar yang diurutkan. Anda fundamental harus melihat setiap elemen dari dan B . Sketsa pembenaran informal: Jika ada elemen yang belum Anda lihat, Anda tidak bisa menampilkannya, jadi satu-satunya kasus di mana Anda dapat menghilangkan melihat elemen adalah jika Anda tahu elemen itu ada di A dan B , tetapi bagaimana Anda bisa tahu bahwa itu ada jika Anda belum melihat nilainya?A B A B
sumber
Jika A dan B memiliki ukuran yang sama, disjoint dan interleaved (mis. Angka ganjil dalam A dan angka genap di B), maka perbandingan berpasangan item dalam waktu linier mungkin optimal.
Jika A dan B berisi blok item yang berada tepat di salah satu dari A atau B, atau di keduanya, dimungkinkan untuk menghitung perbedaan set, penyatuan dan persimpangan dalam waktu sub linier. Sebagai contoh, jika A dan B berbeda dalam satu item, maka perbedaannya dapat dihitung dalam O (log n).
http://arxiv.org/abs/1301.3388
sumber
sumber
long
dapat menyimpan 32 elemen atau 1byte
, 8 elemen. sehingga entri 1M hanya dapat disimpan dalam ~ 125K RAM! penyimpanan dapat secara signifikan lebih efisien daripada representasi lainnya tergantung pada bagaimana masalahnya diimplementasikan ...