Standard Template Library Uluslararası Bilgisayar Enstitüsü Ege Üniversitesi Ahmet Bilgili & Serkan Ergun
STL ANSI/ISO Standard C++ ın içerdiği algoritmalar ANSI/ISO Standard C++ ın içerdiği algoritmalar ve sınıflar kütüphanesidir.
Konteynırlar Nesneleri saklayabileceğimiz yapılardır. vector, list, set, map, Tüm STL konteynırlarında tanımlı 2 fonksiyon vardır size() saklanan nesnelerin sayısını döndürür empty() konteynırın boş olup olmadığını döndürür. Konteynırlarda saklanan nesnelerin copy constructor ve assignment operatörü olması gerekir. (derleyici varsayılan olarak üretir)
Iterator Tipi ne olursa olsun tüm konteynırların içerdiği nesneleri gezebilmek için kullanılır. Örnek: vector<int> intvector; // stl container (vector) // container içerisindeki ilk nesneyi gösteren iterator vector<int>::iterator it = intvector.begin(); // vector'ün sonuna gelmediğimiz sürece while(it!= intvector.end()) { // iterator'un gösterdiği nesneyi al int obj = *it; // bir sonraki nesneye git ++it; }
vector Dizilerden farksızdır. İstediğiniz elemanına doğrudan ulaşabilme imkanı verir. push_back() ile vektörün sonuna nesne eklenebilir, sınırların kontrol edilmesine gerek yoktur, yeniden boyutlandırmayı kendi içerisinde halleder. Hafıza alanı ayırma işini kendi içerisinde halleder. Önceden ayırdığı bellek dolunca, iki katı kadar bir blok ayırıp eski nesneleri yeni bellek alanına taşır.
vector vector<int> intvector; vector<int>::iterator it; int sum = 0; intvector.reserve(10); for(int i = 0; i < 10; i++) intvector.push_back(i); it = intvector.begin(); while(it!= intvector.end()) { int obj = *it; sum = sum + obj; ++it; } // vektör tanımı // vektör iterator ü tanımı // Bellekte yer hazırlar. Bu işlem zorunlu değildir, // yeniden boyutlandırma sırasında olan kopyalama // ek yükünü önlemek için kullanılmıştır. // vektörün sonuna nesneleri ekle // vektördeki ilk nesneyi gösteren iterator // vektörün sonuna gelmediğimiz sürece // iterator'un gösterdiği nesneyi al // toplama nesneyi ekle // bir sonraki nesneye git intvector.insert(intvector.begin(), sum); // toplamı vektörün başına ekle intvector.pop_back(); // vektörün sonundan nesne sil int thirdobj = intvector[2]; // vektörde 3. sırada bulunan nesne
list Nesneleri doubly linked list yapısında saklar Nesneler vektördeki gibi tek hafıza bloğu yerine parça parça bloklara dağılmışlardır. Nesnelere rastgele erişim O(n) zamanda gerçekleşir. Listenin herhangi bir yerinde ekleme / çıkarma yapmak sabit zamanda gerçekleşir. Nesnelerin vektörde olduğu gibi taşınmasına gerek yoktur.
list list<int> intlist; list<int>::iterator it; int sum = 0; for(int i = 0; i < 10; i++) intlist.push_back(i); it = intlist.begin(); while(it!= intlist.end()) { int obj = *it; sum = sum + obj; ++it; } intlist.push_front(sum); intlist.pop_back(); // liste tanımı // liste iteratorü // listenin sonuna nesneleri ekle // listede ilk nesneyi gösteren iterator // listenin sonuna gelmediğimiz sürece // iteratorün gösterdiği nesneyi al // nesneyi toplama ekle // listedeki bir sonraki nesneye git // toplamı listenin başına ekle // listenin sonundan nesne çıkar intlist.insert(++intlist.begin(),12); // listenin 2. nesnesinden önce yeni bir nesne ekle
set Nesneleri küme yapısında sıralı bir şekilde saklar. Aynı değere sahip iki farklı nesneye izin vermez. Sıralı oldukları için O(logn) zamanda ekleme çıkarma ve arama yapılır.
set set<int> intset; set<int>::iterator it; int sum = 0; for(int i = 0; i < 10; i++) intset.insert(i % 4); it = intset.begin(); while(it!= intset.end()) { int obj = *it; sum = sum + obj; ++it; } intset.erase(1); it = intset.find(2); if(it!= intset.end()) intset.erase(it); // küme tanımı // küme iteratorü // kümeye nesneleri ekle // kümede ilk nesneyi gösteren iterator // kümenin sonuna gelmediğimiz sürece // iteratorün gösterdiği nesneyi al // nesneyi toplama ekle // kümedeki bir sonraki nesneye git // kümeden 1 değerini sil // kümede 2 değerini ara // 2 değeri bulunduysa // bulunan nesneyi sil
map Nesneleri bir anahtara göre sıralayıp saklamak için kullanılır Anahtar ile nesnelere O(logn) zamanda ulaşabilmeyi sağlar. Aynı anahtara sahip 2 farklı değer eklenmesine izin vermez.
map<string, int> mmonths; map<string, int>::iterator mmonthsiterator; // map'e nesne ekleme mmonths["january"] = 31; mmonths["february"] = 28; mmonths["march"] = 31; mmonths["april"] = 30; mmonths["may"] = 31; mmonths["june"] = 30; mmonths["july"] = 31; mmonths["august"] = 31; mmonths["september"] = 30; mmonths["october"] = 31; mmonths["november"] = 30; mmonths["december"] = 31; // map tanımı // map iterator'ü tanımı map mmonthsiterator = mmonths.begin(); // map'deki ilk nesneyi gösteren iterator while(mmonthsiterator!= mmonths.end()) // map'in sonuna gelmediğimiz sürece { cout << mmonthsiterator->first << " has " // iterator'ün gösterdiği nesnenin anahtarı ve << mmonthsiterator->second << " days" // değerini ekrana yazdır << endl; mmonthsiterator++; // map'deki bir sonraki nesneye git } mmonths.erase("april"); mmonthsiterator = mmonths.find("august"); if(mmonthsiterator!= mmonths.end()) mmonths.erase(mmonthsiterator); // map'den "april" anahtarlı nesneyi sil // "august" anahtarlı nesneyi ara // nesne bulunduysa // nesneyi map'den sil.
Functor lar Fonksiyon objeleri, (ya da functor lar) fonksiyon gibi çağırılabilecek nesnelerdir. Fonksiyon pointer ları, ya da operator() tanımlı olan herhangi bir sınıf Functor olarak kullanılabilir. STL de parametre almayan ve 1, ve 2 parametre alan functor lar kullanılır.
Functor lar set<int, less<int>> setlesser; // küçükten büyüğe sıralama set<int, greater<int>> setgreater; // büyükten küçüğe sıralama set<int, abslesser > setabslesser; // mutlak değere göre sıralama // yukarıdaki functor objesi yerine function pointer da kullanılabilir: //set<int, bool(*)(int,int)> setabslesser(abslesserfunc); for(int i = 0; i < 10; i++) { int j = i % 5-2; setlesser.insert(j); setgreater.insert(j); setabslesser.insert(j); } // kümeye nesneleri ekle // kümeye nesneleri ekle // kümeye nesneleri ekle cout << "kucukten buyuge siralama" << endl; copy(setlesser.begin(), setlesser.end(), ostream_iterator<int>(cout, "\n")); cout << "buyukten kucuge siralama" << endl; copy(setgreater.begin(), setgreater.end(), ostream_iterator<int>(cout, "\n")); cout << "mutlak degere gore siralama" << endl; copy(setabslesser.begin(), setabslesser.end(), ostream_iterator<int>(cout, "\n")); // mutlak değerlere göre // sıralayan functor objesi struct abslesser { bool operator() (int i, int j) { return abs(i) < abs(j); } }; // mutlak değere göre // sıralayan fonksiyon bool abslesserfunc(int i, int j) { return abs(i) < abs(j); }
sort Rastgele erişimin yapılabildiği konteynırlarda nesneleri sıralamak için kullanılır. Sıralama algoritması olarak en kötü durumda O(nlogn) zamanda çalışan Introsort algoritmasını kullanır. Introsort, Quicksort ile başlayıp Heapsort ile devam ederek en kötü durumda O(nlogn) zamanda çalışmayı garantiler.
sort cout << "sort testleri: " << endl; // 10 integer içeren vector tanımı vector<int> intvector(10); //vector'ü rasgele sayılarla doldur generate(intvector.begin(), intvector.end(), rand); //ekranda göster cout << "siralamadan once" << endl; copy(intvector.begin(), intvector.end(), ostream_iterator<int>(cout, "\n")); //vector'ü büyükten küçüğe sırala sort(intvector.begin(), intvector.end(), greater<int>()); //ekranda göster cout << "siraladiktan sonra" << endl; copy(intvector.begin(), intvector.end(), ostream_iterator<int>(cout, "\n"));
for_each Functor for_each(iterator first, iterator last, Functor f); for_each; verilen iterator aralığındaki nesnelere, for_each; verilen iterator aralığındaki nesnelere, functor nesnesini uygular.
for_each struct sum { public: int total; sum() : total(0) {} void operator()(int i) { total += i; } }; // 10 integer içeren vector tanımı vector<int> intvector(10); //vector'ü rasgele sayılarla doldur generate(intvector.begin(), intvector.end(), rand); //ekranda göster copy(intvector.begin(), intvector.end(), ostream_iterator<int>(cout, "\n")); sum result = for_each(intvector.begin(), intvector.end(), sum()); cout << "toplam: " << result.total << endl;
find ve binary_search iterator find(iterator first, iterator last, value v); bool binary_search(iterator first, iterator last, value v); iterator lower_bound(iterator first, iterator last, value v); iterator upper_bound(iterator first, iterator last, value v); find; [first, last) aralığında v değerini O(n) zamanda arar, bulduğu ilk değeri gösteren iterator ü döndürür. binary_search; sıralı [first, last) aralığında v değerini O(logn) zamanda arar. lower_bound; sıralı [first, last) aralığında sıralamayı bozmadan v değerini ekleyebileceği ilk konumun iterator ünü döndürür. upper_bound; sıralı [first, last) aralığında sıralamayı bozmadan v değerini ekleyebileceği son konumun iterator ünü döndürür.
find ve binary_search vector<int> intvector; vector<int>::iterator it; // sıralı olmayan vektör değerleri oluştur: for(int i = 0; i < 10; i++) intvector.push_back((i + 5) % 8); //ekranda göster copy(intvector.begin(), intvector.end(), ostream_iterator<int>(cout, " ")); // 4 değerini ara cout << "find: 4 "; it = find(intvector.begin(), intvector.end(), 4); if(it!= intvector.end()) cout << "bulundu" << endl; else cout << "bulunamadi" << endl; //vektörü sırala sort(intvector.begin(), intvector.end()); //sıralı vektörde -1 değerini ara cout << "binary_search: -1 " << endl; if(binary_search(intvector.begin(), intvector.end(), -1)) cout << "bulundu" << endl; else cout << "bulunamadi" << endl; // sıralı vektörde sıralamayı değiştirmeden 5 // değerini ekleyebileceğimiz ilk konum it = lower_bound(intvector.begin(), intvector.end(), 5); cout << "5 icin lower_bound: " << it - intvector.begin() << endl; // sıralı vektörde sıralamayı değiştirmeden 5 // değerini ekleyebileceğimiz son konum it = upper_bound(intvector.begin(), intvector.end(), 5); cout << "5 icin upper_bound: " << it - intvector.begin() << endl;
http://www.sgi.com/tech/stl/
Teşekkürler