Saya memerlukan algoritma pencarian biner yang kompatibel dengan wadah C ++ STL, seperti std::binary_search
di <algorithm>
header perpustakaan standar , tetapi saya membutuhkannya untuk mengembalikan iterator yang menunjuk pada hasil, bukan boolean sederhana yang memberi tahu saya jika elemen itu ada.
(Sebagai catatan tambahan, apa yang dipikirkan komite standar ketika mereka mendefinisikan API untuk binary_search ?!)
Perhatian utama saya di sini adalah bahwa saya memerlukan kecepatan pencarian biner, jadi meskipun saya dapat menemukan data dengan algoritme lain, seperti yang disebutkan di bawah ini, saya ingin memanfaatkan fakta bahwa data saya diurutkan untuk mendapatkan manfaat dari biner pencarian, bukan pencarian linier.
sejauh ini lower_bound
dan upper_bound
gagal jika datum hilang:
//lousy pseudo code
vector(1,2,3,4,6,7,8,9,0) //notice no 5
iter = lower_bound_or_upper_bound(start,end,5)
iter != 5 && iter !=end //not returning end as usual, instead it'll return 4 or 6
Catatan: Saya juga baik-baik saja menggunakan algoritme yang tidak termasuk dalam namespace std asalkan kompatibel dengan container. Seperti, katakanlah boost::binary_search
,.
sumber
Jawaban:
Tidak ada fungsi seperti itu, tetapi Anda dapat menulis yang sederhana menggunakan
std::lower_bound
,std::upper_bound
ataustd::equal_range
.Implementasi sederhana bisa jadi
Solusi lain adalah menggunakan a
std::set
, yang menjamin pengurutan elemen dan menyediakan metodeiterator find(T key)
yang mengembalikan iterator ke item yang diberikan. Namun, persyaratan Anda mungkin tidak kompatibel dengan penggunaan satu set (misalnya jika Anda perlu menyimpan elemen yang sama beberapa kali).sumber
*i == val
! Lebih baik digunakan!(val < *i)
. Alasannya adalah karenalower_bound
menggunakan<
, bukan==
(yaituT
bahkan tidak diperlukan untuk dapat dibandingkan dengan kesetaraan). (Lihat STL Efektif Scott Meyers untuk penjelasan tentang perbedaan antara kesetaraan dan kesetaraan .)end
. Rentang di pustaka standar C ++ diwakili dengan interval setengah terbuka: "poin" iterator akhir setelah elemen terakhir. Dengan demikian, dapat dikembalikan oleh algoritme untuk menunjukkan bahwa tidak ada nilai yang ditemukan.Anda harus melihatnya
std::equal_range
. Ini akan mengembalikan sepasang iterator ke kisaran semua hasil.sumber
Ada satu set di antaranya:
http://www.sgi.com/tech/stl/table_of_contents.html
Pencarian untuk:
Di catatan terpisah:
Mereka mungkin berpikir bahwa penampung penelusuran dapat menghasilkan lebih dari satu hasil. Tetapi pada kesempatan aneh di mana Anda hanya perlu menguji keberadaan versi yang dioptimalkan juga akan menyenangkan.
sumber
Jika std :: lower_bound terlalu rendah untuk Anda sukai, Anda mungkin ingin memeriksa boost :: container :: flat_multiset . Ini adalah pengganti drop-in untuk std :: multiset yang diimplementasikan sebagai vektor yang diurutkan menggunakan pencarian biner.
sumber
Implementasi terpendek, bertanya-tanya mengapa tidak disertakan dalam pustaka standar:
Dari https://en.cppreference.com/w/cpp/algorithm/lower_bound
sumber
Periksa fungsi ini, qBinaryFind :
Fungsi ini termasuk dalam
<QtAlgorithms>
tajuk yang merupakan bagian dari pustaka Qt .sumber
std :: lower_bound () :)
sumber
Contoh: Misalkan sebuah array, A = [1,2,3,4,5,6,7,8,9] Misalkan Anda ingin mencari indeks 3 Awalnya, start = 0 dan end = 9-1 = 8 Sekarang , sejak awal <= akhir; pertengahan = 4; (array [mid] yaitu 5)! = 3 Sekarang, 3 terletak di kiri mid karena lebih kecil dari 5. Oleh karena itu, kita hanya mencari bagian kiri array. Oleh karena itu, sekarang start = 0 dan end = 3; mid = 2. Sejak array [mid] == 3, maka kita mendapatkan nomor yang kita cari. Karenanya, kami mengembalikan indeksnya yang sama dengan mid.
sumber
Solusi yang mengembalikan posisi di dalam rentang bisa seperti ini, hanya menggunakan operasi pada iterator (itu harus berfungsi bahkan jika iterator tidak aritmatika):
sumber