- Bir görev için uygun STL kapsayıcısını seçmek
std::mapile anahtar–değer çiftlerini saklamak ve saymakstd::setile tekrarsız elemanlardan oluşan bir topluluk oluşturmak- Yineleyiciler ve
<algorithm>fonksiyonlarıyla sıralamak, aramak ve saymak
Bir olimpiyatta bir milyon sayıyı sıralaman gerekiyor. Bir sıralama algoritmasını sıfırdan yazıp hatalarını ayıklamak bir saat sürer. C++ programcısı ise tek bir satır yazar: std::sort(v.begin(), v.end());. Bu sihir STL'den (Standard Template Library, Standart Şablon Kütüphanesi) gelir: hazır, denenmiş ve çok hızlı veri yapıları ile algoritmalardan oluşan bir koleksiyon.
STL'nin üç parçası
- Kapsayıcılar verileri saklar:
std::vector,std::map,std::setve diğerleri. - Yineleyiciler (iterator) kapsayıcıdaki bir konumu gösterir:
v.begin()ilk elemanı,v.end()ise sonuncudan sonraki yeri gösterir. - Algoritmalar (
<algorithm>dosyasından) yineleyicilerle verilen bir aralık üzerinde çalışır: sıralar, arar, sayar, dönüştürür.
| Kapsayıcı | Ne saklar | Arama hızı |
|---|---|---|
std::vector<T> | sıralı elemanlar, indisle | değere göre arama: O(n) |
std::map<K, V> | anahtara göre sıralı anahtar–değer çiftleri | O(log n) |
std::set<T> | sıralı, tekrarsız elemanlar | O(log n) |
std::unordered_map<K, V> | sırasız anahtar–değer çiftleri (karma tablosu) | ortalama O(1) |
std::map: anahtarlar ve değerler
std::map (<map> dosyasından) bir sözlük gibidir: her anahtara bir değer karşılık gelir ve anahtarlar tekrarlanmaz. Elemanlar her zaman anahtara göre sıralı tutulur. Aşağıda bir sınıf anketinin oylarını sayıyoruz: count[v], anahtar yoksa onu 0 değeriyle oluşturur, ++ ise değeri artırır.
#include <iostream>
#include <map>
#include <string>
#include <vector>
int main() {
std::vector<std::string> votes = {"tea", "coffee", "tea", "juice", "tea", "coffee"};
std::map<std::string, int> count;
for (const std::string& v : votes) {
count[v]++;
}
for (const auto& entry : count) {
std::cout << entry.first << ": " << entry.second << '\n';
}
std::cout << "Kinds: " << count.size() << '\n';
if (count.find("milk") == count.end()) {
std::cout << "Nobody chose milk\n";
}
return 0;
}coffee: 2 juice: 1 tea: 3 Kinds: 3 Nobody chose milk
pair'dir: first anahtar, second değerdir.std::set: tekrarsız elemanlar
std::set (<set> dosyasından) her değeri yalnızca bir kez saklar ve elemanları otomatik olarak sıralar. Zaten var olan bir değeri insert ile eklersen hiçbir şey değişmez. Tekrarları silmek ve “bu değer daha önce geldi mi?” sorusunu hızla yanıtlamak için idealdir.
#include <iostream>
#include <set>
int main() {
std::set<int> numbers = {5, 1, 4, 1, 5, 9, 2, 6, 5};
numbers.insert(3);
numbers.insert(4);
std::cout << "Size: " << numbers.size() << '\n';
for (int n : numbers) {
std::cout << n << ' ';
}
std::cout << '\n';
std::cout << std::boolalpha << (numbers.count(7) > 0) << '\n';
return 0;
}Size: 7 1 2 3 4 5 6 9 false
Algoritmalar
<algorithm> içinde onlarca hazır fonksiyon vardır ve hepsi aynı şekilde çalışır: bir aralığın başını ve sonunu yineleyici olarak alırlar. std::find bulduğu elemanın yineleyicisini, hiçbir şey bulamazsa end() döndürür. Toplama için <numeric> dosyasında std::accumulate vardır.
#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
int main() {
std::vector<int> v = {42, 7, 19, 73, 7, 50};
std::sort(v.begin(), v.end());
for (int x : v) {
std::cout << x << ' ';
}
std::cout << '\n';
auto it = std::find(v.begin(), v.end(), 19);
if (it != v.end()) {
std::cout << "19 found at index " << (it - v.begin()) << '\n';
}
std::cout << "Sevens: " << std::count(v.begin(), v.end(), 7) << '\n';
std::cout << "Max: " << *std::max_element(v.begin(), v.end()) << '\n';
std::cout << "Sum: " << std::accumulate(v.begin(), v.end(), 0) << '\n';
return 0;
}7 7 19 42 50 73 19 found at index 2 Sevens: 2 Max: 73 Sum: 198
| Algoritma | Ne yapar |
|---|---|
std::sort(b, e) | artan sırada sıralar |
std::reverse(b, e) | sırayı tersine çevirir |
std::find(b, e, x) | x'in yineleyicisini ya da e'yi döndürür |
std::count(b, e, x) | x'in kaç kez geçtiğini sayar |
std::max_element(b, e) | en büyük elemanın yineleyicisi |
std::binary_search(b, e, x) | sıralı bir aralıkta hızlı arama, true/false |
std::sort ise yaklaşık n · log n karşılaştırmayla çalışır; bir milyon eleman için bu, binlerce kat daha azdır.Önemli noktalar
- STL = kapsayıcılar + yineleyiciler + algoritmalar.
std::map, anahtara göre sıralı anahtar–değer çiftleri saklar;m[k]olmayan anahtarı 0 ile oluşturur.std::sether değeri bir kez ve sıralı olarak saklar.v.end()son elemandan sonraki yerdir;std::findbir şey bulamazsa onu döndürür.std::sort,std::count,std::max_elementgibi hazır algoritmalar elle yazılmış döngülerden daha kısa ve güvenilirdir.
Kendini test et
10 soru. Her doğru cevap XP kazandırır.