İçeriğe geç
Educora
İleri20 dk9 / 10

STL: kapsayıcılar ve algoritmalar

Standart Şablon Kütüphanesi ile çalış: `std::map`, `std::set`, yineleyiciler ve `std::sort`, `std::find`, `std::count` gibi hazır algoritmalar.

Kendini test et
Bu derste öğreneceklerin
  • Bir görev için uygun STL kapsayıcısını seçmek
  • std::map ile anahtar–değer çiftlerini saklamak ve saymak
  • std::set ile 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::set ve 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 saklarArama hızı
std::vector<T>sıralı elemanlar, indisledeğere göre arama: O(n)
std::map<K, V>anahtara göre sıralı anahtar–değer çiftleriO(log n)
std::set<T>sıralı, tekrarsız elemanlarO(log n)
std::unordered_map<K, V>sırasız anahtar–değer çiftleri (karma tablosu)ortalama O(1)
En çok kullanılan kapsayıcılar

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.

C++
#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;
}
Beklenen çıktı
coffee: 2
juice: 1
tea: 3
Kinds: 3
Nobody chose milk
Anahtarlar alfabetik sırayla yazıldı. Her eleman bir 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.

C++
#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;
}
Beklenen çıktı
Size: 7
1 2 3 4 5 6 9 
false
Dokuz sayıdan altısı tekrarsızdır; 3 eklendi, 4 ise zaten vardı.

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.

C++
#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;
}
Beklenen çıktı
7 7 19 42 50 73 
19 found at index 2
Sevens: 2
Max: 73
Sum: 198
AlgoritmaNe 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
Etkileşimli
Simülasyon yükleniyor…
Basit sıralama algoritmaları yaklaşık n² adım atar. 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::set her değeri bir kez ve sıralı olarak saklar.
  • v.end() son elemandan sonraki yerdir; std::find bir şey bulamazsa onu döndürür.
  • std::sort, std::count, std::max_element gibi 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.

1 / 10
Hangi kapsayıcı elemanlarını tekrarsız ve sıralı tutar?