Haftalık C++ 2 – Konteynerler ve sıralı tutma

Merhaba arkadaşlar,

Haftalık C++ kod örneklerimize devam ediyoruz. Bu haftaki problemimiz std::vector gibi konteynerlere (nedir arkadaş bu STL konteyner sevdası yahu 🙂 duyar gibiyim) bir yandan veri eklerken bir yandan da bunları sıralı tutabilir miyiz?

Bu probleme geçmeden önce konteyner konusuna ufak bir eğilelim, çünkü buradaki problemi çözerken bir miktar değinmemiz gerekecek. Bu sınıfların detaylarına girmeyeceğim ama merak edenler bu sayfaya göz atabilirler. Burada her bir sınıfa ilişkin detaylı bilgi, performans ve servisler sıralanmaktadır.

STL günlük hayatta ihtiyaç duyabileceğimiz veri yapılarına (queue, stack, linked list, vs) ilişkin bir çok konteyner sınıfını içerisinde barındırıyor. Genel olarak bunlar oldukça hızlı ve verimli bir şekilde gerçeklenmiş durumda. Hepsi ortak arayüzler sunuyorlar ve iyi bir şekilde dökümante edilmiş durumdalar. Genel olarak bu konteynerler dört ana gruba ayrılıyor:

  • Sıralı Konteynerler (“Sequence containers”)
    • Aynı tip verileri sıralı bir şekilde saklayan veri yapılarını ifade etmek için kullanılırlar,
    • Bu grup altında array (statik veri dizisi), vector (dinamik veri dizisi), forward_list (tek yönlü bağlı liste), list (çift yönlü bağlı liste) ve deque (çift yönlü kuyruk) konteynerleri var.
  • İlişkili Konteynerler (“Associative containers”)
    • Hızlı erişime olanak sağlamak adına sıralı veri yapıları sunan konteynerleri kapsar,
    • Bu grup altında set (tekli sıralı küme), map (tekli ilişkili dizi, anahtarlara göre sıralı) , multiset (çoklu sıralı küme), multimap (çoklu ilişkili dizi, anahtarlara göre sıralı) konteynerleri var.
  • Sırasız Konteynerler (“Unordered containers”)
    • İlişkili dizilerden farklı olarak sırasız fakat hızlı erişim ( en kötü durumda O(n)  ) adına hash kullanan veri yapılarını ifade eden konteynerleri içerisinde barındırır,
    • Bu sınıflar C++ 11 ile birlikte sunulmaya başlandılar,
    • Bu grup altında unordered_set, unordered_map, unordered_multiset ve unordered_multimap konteynerlerini içerisinde barındırır. Bunlar ilişkili konteynerlerin hash kullanan karşılıklarıdır.
  • Konteyner Adaptörleri (“Container adapters”)
    • Bunlar alında kendi başlarına bir konteyner olmayan, daha çok yukarıdakileri kullanan/sarmalayan sınıflar olarak düşünülebilir,
    • Bu grup altında stack (“LIFO – Last in first out” yığın veri yapısı), queue (“LILO – Last in last out” kuyruk veri yapısı) ve priority_queue konteynerleridir. Bunlara ilişkin kabiliyet ve servisler vector, deque ve list ile de sunulabilmekte.

Şimdi gelelim problemimize elimizde sıralı konteynerler var (ör. vector) ve eklediğimiz her eleman ile sıranın bozulmadan korunmasını istiyoruz bunu kolay bir şekilde nasıl yapabiliriz?

İlk yöntem her ekleme sonrası “algorithm” kütüphanesi tarafından sunulan sort() metodunu kullanmak olabilir ki tahmin edeceğiniz üzere pek ucuz bir yöntem olmayacaktır 🙂 Neyse aşağıda örnek bir vector ilklendirelim ve bunu sıralayalım.

Evet sıralı eklemek için yine “algorithm” kütüphanesinden bir metottan yardım alacağız. Bu metot lower_bound().  Aşağıda bu metodun tanımını görebilirsiniz:

Metot kısaca [First, Last) aralığındaki verilen val değerinden küçük olmayan ilk elemanı işaret eden iterator’ü dönüyor.

Örneğin: {10, 20, 30, 40, 50} girdisi için 10 ve 50 arasında 35 değeri için bu metot 3 dönecek, 15 için ise 1 dönecek.

Aşağıda bu metodun ve kardeşinin (upper_bound()) kullanıma ilişkin örnek bir kod ta görebilirsiniz:

Şimdi geldi sıra assolistimize (addSorted) 🙂

addSorted() metodu nasıl çalışıyor? Aslında bütün espri lower_bound() metodunda bütün listeyi bu metoda geçiriyoruz ve o da bize değeri ekleyeceğimiz yeri dönüyor. Daha sonra da vector sınıfının insert() metodu ile elemanı ekliyoruz.

Tabi şimdi bunu diğer konteynerler de kullanamaz mıyız diye sorduğunu duyar gibiyim. Elbette sevgili yazılımperver dostum elbette. Bunun için “template” ları kullanacağız. Aşağıda daha jenerik addSorted() metodumuz ve bunu list ile olan kullanımını bulabilirsin.

Bir sonraki haftalık C++ yazımda görüşmek üzere.

Kendinize iyi bakın.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

This site uses Akismet to reduce spam. Learn how your comment data is processed.