Mencari sebuah nilai di dalam container adalah kebutuhan harian, dan C++ menyediakan std::find untuk itu: algoritma linier yang memeriksa elemen satu per satu dari first hingga last, membandingkan tiap elemen dengan nilai yang dicari lewat operator==. Sepuluh tahun kuliah ilmu komputer tidak diperlukan untuk menghafalnya — yang penting dipahami adalah nilai kembaliannya, yaitu iterator. std::find mengembalikan iterator ke elemen pertama yang cocok, atau last bila tidak ada yang cocok. Chapter ini membahas std::find, saudaranya find_if untuk kondisi bebas, cara menafsirkan hasil pencarian, dan pola counting untuk menghitung semua kemunculan.
std::find dan Hasil yang Dikembalikan #
Aturan baca hasilnya satu kalimat: bandingkan iterator yang dikembalikan dengan end(). Bila sama, pencarian gagal; bila berbeda, iterator menunjuk elemen yang ditemukan dan selisihnya dengan begin() adalah indeksnya. Program berikut menunjukkan kedua cabang tersebut:
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> stok = {12, 7, 25, 7, 9, 30};
// std::find: mencari nilai dengan operator==, linier O(n)
auto posisi = std::find(stok.begin(), stok.end(), 25);
if (posisi != stok.end()) {
std::cout << "25 ditemukan di indeks "
<< (posisi - stok.begin()) << "\n";
}
// end() berarti nilai tidak ditemukan
auto hilang = std::find(stok.begin(), stok.end(), 99);
std::cout << "Cari 99: "
<< (hilang == stok.end() ? "tidak ditemukan" : "ditemukan")
<< "\n";
// find_if: kondisi bebas lewat lambda
auto pertamaGenap = std::find_if(stok.begin(), stok.end(),
[](int x) { return x % 2 == 0; });
std::cout << "Genap pertama: " << *pertamaGenap << "\n";
// Pola counting: ulangi find dari posisi setelah temuan terakhir
int jumlahTujuh = 0;
for (auto it = std::find(stok.begin(), stok.end(), 7);
it != stok.end();
it = std::find(it + 1, stok.end(), 7)) {
++jumlahTujuh;
}
std::cout << "Angka 7 muncul: " << jumlahTujuh << " kali\n";
return 0;
}Output yang Dihasilkan:
25 ditemukan di indeks 2
Cari 99: tidak ditemukan
Genap pertama: 12
Angka 7 muncul: 2 kaliBedah baris demi baris:
- Baris 8-11 (
std::find(stok.begin(), stok.end(), 25)): pencarian nilai25berhasil;posisimenunjuk elemen tersebut danposisi - stok.begin()menghasilkan indeks2. Pengurangan iterator sah di sini karena vector memberi random access. - Baris 14-16: nilai
99tidak ada, sehingga hasilstd::findsama denganend(). Kode kita menafsirkannya sebagai"tidak ditemukan"— inilah konvensi yang dipakai semua algoritma pencarian. - Baris 19-21 (
std::find_if): alih-alih nilai tetap, kita mengirim lambdax % 2 == 0.find_ifmengembalikan elemen pertama yang membuat lambda menghasilkantrue; di data ini12. - Baris 24-29: pola counting. Loop dimulai dari temuan pertama; setiap iterasi mencari lagi mulai
it + 1, sehingga setiap kemunculan7dihitung satu kali hinggaend()tercapai. Hasilnya dua kali.
Pola counting di baris 24-29 sesungguhnya bisa digantikan std::count (Chapter berikutnya pada bagian pencacahan), tetapi bentuk ini bermanfaat saat kita butuh posisi setiap kemunculan, bukan sekadar jumlahnya.
find_if untuk Kondisi Bebas #
std::find hanya bisa membandingkan kesamaan nilai. Dunia nyata sering bertanya lain: “cari mahasiswa dengan nilai di bawah 60”, “cari produk yang stoknya nol”, “cari string yang kosong”. Untuk pertanyaan-pertanyaan seperti itu, find_if menerima predikat — fungsi satu argumen yang mengembalikan bool. Kombinasi lambda dan find_if menjadi alat pencarian paling serbaguna karena kondisinya ditulis langsung di tempat pemanggilan.
Ada juga varian find_if_not yang mencari elemen pertama yang tidak memenuhi predikat, serta std::search untuk mencari sub-urutan di dalam urutan yang lebih panjang. Keluarga ini semuanya linier dan hanya menuntut input iterator, sehingga aman dipakai di container mana pun, termasuk std::list dan std::set.
Satu kebiasaan yang patut dijaga: selalu periksa hasil terhadap end() sebelum mendereference. Menulis *std::find(...) langsung tanpa pemeriksaan adalah bug menunggu data berubah, karena bila nilai tidak ditemukan kita sedang mendereference end() — perilaku undefined.
Berikutnya kita naikkan kecepatan pencarian dengan menuntut syarat pada data: binary search, lower_bound, upper_bound, dan equal_range.
Rujukan resmi: std::find, find_if, find_if_not .