kapta her bir değerden kaç tane olduğunu saymak

Bir kap (container) içinde tutulan her bir değerdeki öğeden kaç tane olduğunu nasıl sayarız? Soruyu bir kodla daha açık hale getirelim:

main işlevinde oluşturulan ivec isimli kapta [0-99] aralığında 1000 tamsayı tutuluyor. Bu tamsayıların herbirinden kaç tane olduğunu bulmamız ve bu değerleri kullanıcı ekranına yazdırmamız gereksin.

Bu amaçla standart kütüphanenin map ya da unordered_map sınıflarının [ ] işlevini kullanabiliriz:

Önce burada işimizi gören [] işlevinin bildirimine bir bakalım:

Üye işlevimizin geri dönüş değeri olan mapped_type ve parametre değişkeni türü olan key_type map sınıf şablonunun birinci ve ikinci şablon tür parametrelerine verilen eşisimler:

Birinci şablon tür parametresinin eşismi olan key_type anahtar olarak kullanılan değerin türü iken ikinci şablon tür parametresine eşisim olan mapped_type ise anahtara karşılık gelen değerin türü. Bilindiği gibi map kabının gerçekleştirimi (implementation) tipik olarak içinde anahtar değer çiftleri tutan bir ikili arama ağacı olarak yapılıyor.  Örneğin std::map<int, int> türünden bir kap nesnesi içinde std::pair<const int, int> türünden değerler tutuyor.

Kodda tanımlanan cmap nesnesinin tuttuğu std::pair<const int, int> nesnelerimizin first’ü sayılacak değerler second’ı ise bu değerden kaç tane olduğunu tutacak sayaçlarımız olarak görev yapacak.

[] işlevimiz bir anahtar değeri alıp bunun karşılığında bizi o anahtara karşılık gelen değere eriştiriyor. multimap ve unordered multimap kaplarının  böyle bir işlevi yok. Çünkü bu kaplarda aynı anahtara sahip birden fazla değer tutulabiliyor.

[] işlevinin ilginç bir davranışı var: Eğer map içinde bu anahtar değeri var ise işlevin geri dönüş değeri map‘te tutulan pair‘in second öğesine referans. Yani map‘te ilgili anahtarın bulunması durumunda doğrudan referans semantiği ile ilgili anahtara karşılk gelen değere erişiyoruz. Peki ya bu anahtar değeri map‘te yer almıyorsa ne oluyor? Bu durumda map kabına yeni bir pair ekleniyor. Eklenen pair‘in first öğesi olarak işleve gönderilen anahtar değeri, second öğesi olarak ise, değerle başlatılan (value initialized) bir mapped_type nesnesi kullanılıyor. Eğer mapped_type varsayılan türlerden birinden ise kurallara göre bu nesne hayata 0 değeriyle başlatılıyor. Bu durumda işlevin geri dönüş değeri eklenen yeni pair‘in second öğesine yani mapped_type türünden nesneye bir referans.
Köşeli parantez işlevi olmasaydı aşağıdaki deyimle yine aynı işi yapabilirdik:
Sınıfın insert işlevinin geri dönüş değeri bir adımlayıcı (iterator). Kapta i anahtarı zaten var ise, yani ekleme işlemi gerçekleştirilmemiş ise geri dönüş değerimiz olan adımlayıcı  bu anahtarı taşıyan pair‘in konumunu tutuyor. Eğer ekleme işlemi gerçekleştirilmiş ise geri dönüş değerimiz yeni eklenmiş pair‘in konumu.

Kodu şimdi içeriden dışarıya açalım:

ifadesi ile mapped_type türünden geçici bir nesne oluşturmuş olduk. Bizim için mapped_type int türü olduğundan oluşturulan int türden geçici nesne 0 degeri ile başlatılacak.

utility başlık dosyasında şablon kodu  bulunan make_pair işlevine yapılan çağrının geri dönüş değeri ile first öğesi i değerinde second öğesi 0 değerinde olan bir pair<int, int> değeri elde ettik:

Buradan elde ettiğimiz pair değerini map sınıfının pair<int, int> parametreli insert işlevine argüman olarak gönderdik:
Bu işlev çağrısından  elde ettiğimiz adımlayıcının  içeriğini alarak referans yoluyla bu konumdaki pair nesnesine eriştik:
nokta işleciyle de pair‘imizin second öğesine eriştik:
++ işleciyle de pair‘imizin second öğesini yani sayaç değerimizi bir arttırmış olduk:
Share

Necati Ergin

C ve Sistem Programcıları Derneğinde eğitmen olarak çalışıyor.

Bunlar da ilginizi çekebilir

Kod Eklemek İçin Okuyun
Eklemek istediğiniz kodları lütfen aşağıdaki “pre” kodları arasında yazınız.
<pre class="lang:c++ decode:true ">
--yazacağınız kodlar--
</pre>
(buradan kopyalayarak kullanabilirsiniz)