Saya mencari cara yang bagus untuk meratakan (membelah) daftar rentang angka yang berpotensi tumpang tindih. Masalahnya sangat mirip dengan pertanyaan ini: Cara tercepat untuk membagi rentang tanggal yang tumpang tindih , dan banyak lainnya.
Namun, rentangnya tidak hanya bilangan bulat, dan saya mencari algoritma yang layak yang dapat dengan mudah diimplementasikan dalam Javascript atau Python, dll.
Contoh Data:
Contoh Solusi:
Mohon maaf jika ini adalah duplikat, tetapi saya belum menemukan solusi.
javascript
algorithms
python
Jollywatt
sumber
sumber
Jawaban:
Berjalan dari kiri ke kanan, menggunakan tumpukan untuk melacak warna apa yang Anda pakai. Alih-alih peta diskrit, gunakan 10 angka dalam dataset Anda sebagai break-point.
Dimulai dengan tumpukan kosong, dan pengaturan
start
ke 0, loop sampai kita mencapai akhir:start
, dan dorong dan semua warna dengan peringkat lebih rendah ke tumpukan. Dalam daftar Anda yang rata, tandai bagian awal warna itu.start
, dan temukan akhir dari warna saat inistart
ke akhir warna ini, keluarkan dari tumpukan, dan periksa warna berperingkat tertinggi berikutnyastart
berada dalam kisaran warna berikutnya, tambahkan warna ini ke daftar yang diratakan, mulai daristart
.Ini adalah mental yang diberikan mengingat data contoh Anda:
sumber
Solusi ini tampaknya yang paling sederhana. (Atau setidaknya, yang paling mudah untuk dipahami)
Yang diperlukan hanyalah fungsi untuk mengurangi dua rentang. Dengan kata lain, sesuatu yang akan memberikan ini:
Yang cukup sederhana. Kemudian Anda dapat dengan mudah mengulangi masing-masing rentang, mulai dari yang terendah, dan untuk masing-masing, kurangi dari semua rentang di atasnya, pada gilirannya. Dan begitulah.
Berikut ini adalah implementasi dari range subtractor dengan Python:
Menggunakan fungsi ini, sisanya dapat dilakukan seperti ini: ('span' berarti rentang, karena 'rentang' adalah kata kunci Python)
Ini memberi
[['red', [12.5, 13.8]], ['blue', [0.0, 2.0]], ['green', [2.0, 3.5]], ['green', [10.0, 12.0]], ['yellow', [3.5, 6.7]], ['orange', [6.7, 10.0]]]
, mana yang benar.sumber
Jika cakupan data benar-benar mirip dengan data sampel Anda, Anda dapat membuat peta seperti ini:
Kemudian cukup berjalan melalui peta ini untuk menghasilkan rentang
Agar berfungsi, nilainya harus dalam kisaran yang relatif kecil seperti pada data sampel Anda.
Sunting: untuk bekerja dengan float sejati, gunakan peta untuk menghasilkan pemetaan tingkat tinggi dan kemudian merujuk ke data asli untuk membuat batas-batas.
sumber
Inilah solusi yang relatif mudah di Scala. Seharusnya tidak terlalu sulit untuk port ke bahasa lain.
apply
mengambilSet
dari semua rentang yang telah diterapkan, menemukan tumpang tindih, lalu mengembalikan set baru dikurangi tumpang tindih dan ditambah rentang baru dan rentang yang baru dipisah.foldLeft
panggilan berulang kaliapply
dengan masing-masing rentang input.sumber
Simpan satu set rentang yang diurutkan berdasarkan mulai. Tambahkan rentang yang mencakup semuanya (-oo .. + oo). Untuk menambahkan rentang r:
sumber