| Üye GİRİŞİ |
std::map ve std::multimap#include <map>
#include <iostream>
using namespace std;
int main()
{
map<string, unsigned long> toplamlar;
string sozcuk;
while (cin >> sozcuk)
{
++toplamlar[sozcuk];
}
cout << "Alfabetik siradaki ilk sozcuk olan '"
<< toplamlar.begin()->first << "' sozcugunu "
<< toplamlar.begin()->second << " kere gordum
";
}
Şimdilik toplamlar.begin() kullanımını bir kenara bırakın;
map'in ögelerinin türlerini biraz sonra anlatacağım.
Burada göstermek istediğim şey, bu programın işinin (sözcüklerin girişte kaç kere görüldüklerinin sayılmasının) tek bir satırda yapılabilmesidir. ++toplamlar[sozcuk] satırını şöyle açıklayabilirim:
1) eğer 'sozcuk' toplulukta yoksa
{
topluluğa o sözcüğe karşılık gelen bir nesne ekle
Bu topluluktaki nesnelerin türleri 'unsigned long'
olduğu için, ve 'unsigned long' türünden nesnelerin
varsayılan kurucuları onlara 0 değerini atadığı için,
bu durumda 'sozcuk' anahtarına karşılık elimizde 0
değeri olacaktır.
}
2) o nesneye erişim sağla
3) o nesnenin değerini bir arttır
Yani o satır işletildiğinde, ilk defa görülen bir sözcüğün değeri 1 olur.
operator[] işlecinin garip kabul edilebilecek bu davranışı, bu tür bir programda kolaylık sağlar. Ancak, yanlış bir kullanımda topluluğa sessizce istenmeyen ögeler eklenmesine de neden olabilir.
Buraya kadar anlattıklarımın std::map topluluk şablonunu hemen kullanmaya başlamak için yeterli olduğuna inanıyorum. Kısaca:
- <map> başlığını kaynak koda ekleyin
- map'i anahtar ve nesne türlerini belirtecek şekilde tanımlayın
- operator[] işleci ile nesneleri hem ekleyin hem de onlara
erişin
map ögesi olarak std::pair
İngilizce'de "çift" anlamına gelen pair, herhangi türden iki nesneyi bir araya getirmek amacıyla kullanılır. pair nesnelerinin her kullanımda neleri temsil ettikleri baştan
bilinemeyeceği için; birinci ve ikinci ögelerine İngilizce karşılıkları olan, sırasıyla 'first' ve 'second' adları verilmiştir.
Tanımladığı tür adlarını ve şablon kurucusunu çıkartırsak, tanımı aşağıdaki programdaki Cift yapı şablonu kadar basittir. Her 'pair' nesnesi kurulurken ögelerinin türlerini de açıkça belirtmek zorunda kalmayalım diye 'make_pair' adlı bir işlev de sunulmuştur.
İşlev şablonları şablon parametrelerinin türlerini işlev parametrelerinden çıkarsayabildikleri için, her seferinde öge türlerini belirtmemek için 'make_pair'i kullanabiliriz.
Bu küçük programda 'make_pair'in Türkçe tanımını da CiftYap adıyla veriyorum:
/*
Tek bir kaydi yazdiran bir islev
*/
ostream & operator<< (ostream & cikis,
RehberKaydi const & kayit)
{
return cikis << kayit.first << ": " << kayit.second;
}
Şimdi yapılması gereken son şey, bütün kayıtları baştan sona çıkışa göndermektir. Bu işi, işlev nesnelerini anlattığım önceki bir yazımda da yaptığım gibi, for döngülerini açıkça yazmak yerine 'copy' algoritmasını kullanarak yapacağım.[5] Eğer
main'in sonuna
ifadesini eklerseniz, rehberdeki kayıtların çıkışa şu şekilde yazdırıldıklarını görürsünüz:
map, içindeki nesneleri sıralı olarak tutar
------------------------------------------
Yukarıdaki çıkışta kayıtların alfabetik sırada a'dan z'ye doğru belirmeleri tesadüf değildir. Standart, map'in nesnelere logaritmik karmaşıklıkta erişim sağlamasını şart koşar. Bunu
sağlamak için map, içindeki nesneleri bir ağaç yapısında tutar.
Bu ağaçtaki nesnelerin hangi sırada sıralanacaklarını map'e kendimiz bildirebiliriz. Bu sıralama yönteminin yukarıdaki programda olduğu gibi, özellikle belirtilmediği durumlarda; map sıralamayı anahtar olarak kullanılan türe operator< işlecini uygulayarak oluşturur. Yani, bizim örneğimizde kullanılan sıralama işleci, operator<(string const &, string const
&)'tır.[6]
O işleç de string'lerin alfabetik sıradaki önceliğine göre sonuç bildirdiği için, nesneler alfabetik sırada sıralanırlar.
Sıralama algoritmasını map'e üçüncü şablon parametresi ile bildirebiliriz. Örneğin kayıtları alfabetik olarak ters sırada sıralamak için map'i şöyle kullanabiliriz:
typedef greater<string> AlfabetikTers;
typedef map<string, TelefonNumarasi, AlfabetikTers> Rehber;
Burada dikkat edilmesi gereken bir nokta, bu Rehber türünün önceki kullandığımız türle uyumsuz hale gelmiş olmasıdır. Bunun nedeni; sınıf şablonlarının türlerini, şablon parametrelerinin belirlemesidir. Sonuçta, örneğin programda
map<string, TelefonNumarasi>
türünün beklendiği bir yerde
map<string, TelefonNumarasi, AlfabetikTers>
türünü kullanamayız; ikisi ayrı türlerdir.
| acehreli 09.11.2003 | |
| Rating : 10 üzerinden 9.00 |
Yorum ekle