D.ershane D Programlama Dili Dersleri

dizi: [array], elemanları yan yana duran ve indeksle erişilen topluluk
eleman: [element], topluluktaki verilerin her biri
eşleme tablosu: [associative array], elemanlarına tamsayı olmayan indekslerle de erişilebilen veri yapısı (bir 'hash table' gerçekleştirmesi)
ilklemek: [initialize], ilk değerini vermek
indeks: [index], topluluk elemanlarına erişmek için kullanılan bilgi
işleç: [operator], bir veya daha fazla değişkenle iş yapan özel işaret (||, &&, +, -, =, vs.)
referans: [reference], asıl nesneye, onun takma ismi gibi erişim sağlayan program yapısı
topluluk: [container], aynı türden birden fazla veriyi bir araya getiren veri yapısı
üst düzey: [high level], donanımdan bağımsız kavramları temsil etmeye elverişli
... bütün sözlük

Bölümler
İngilizce Kaynaklar
Diğer



Eşleme Tabloları

Eşleme tabloları, üst düzey dillerin hepsinde bulunan veri yapılarıdır. Onları, program içine gömülen minik veri tabanları olarak düşünülebilirsiniz. Programlarda çok kullanılan ve çok hızlı veri yapılarıdır.

Dizileri, "elemanları yan yana duran topluluk" olarak tanımlamış ve elemanlarına indeksle erişildiğini görmüştük. Örneğin haftanın günlerinin isimlerini tutan bir dizi şöyle tanımlanabilir:

    string[] günİsimleri =
        [ "Pazartesi", "Salı", "Çarşamba", "Perşembe",
          "Cuma", "Cumartesi", "Pazar" ];

ve, belirli bir günün ismi o diziyi kullanarak şöyle yazdırılabilir:

    writeln(günİsimleri[1]);   // "Salı" yazar

Diziler elemanlara numara ile (indeksle) erişmeye çok uygundurlar, ama bunun tersini yapamazlar. Örneğin elimizde "Salı" dizgisi bulunduğunda onun haftanın 1 numaralı günü olduğunu söyleyemezler (indekslerin 0'la başladıklarını hatırlayın):

    writeln(günSıraları["Salı"]);   // ← derleme HATASI

O satırda "1" yazmayı umuyoruz ama derleme hatası oluşuyor; çünkü dizilerde indeks olarak yalnızca tamsayı türler kullanılabilir; "Salı" gibi dizgiler indeks olamazlar.

Eşleme tablolarının kullanışlılığı işte bu gibi durumlarda ortaya çıkar. Eşleme tabloları, elemanlara yalnızca numara ile değil, herhangi bir türle erişilen veri yapılarıdır.

Görevleri; herhangi bir indeks türündeki bir değeri, herhangi başka bir türdeki değere eşlemektir.

Çok hızlı ama sırasız

Eşleme tabloları arka planda hash table veri yapısını kullandıkları için algoritma karmaşıklığı açısından dizilerden geri kalmazlar: son derece hızlı topluluklardır. Bunun anlamı, içlerindeki eleman sayısından bağımsız olarak, hemen her zaman için sabit zamanda erişim sağlamalarıdır.

Bu kadar hızlı çalışmalarının bedeli, içlerindeki elemanların sıraları konusunda bir şey bilinemiyor olmasıdır. Elemanların ne dizilerdeki gibi yan yana olduklarını, ne de örneğin küçükten büyüğe doğru sıralandıklarını söyleyebiliriz.

Tanımlama

Eşleme tablosu tanımı, dizi tanımına çok benzer. Tek farkı, köşeli parantezler içine dizinin uzunluğu yerine, dizinin indeks türünün gelmesidir. Söz dizimi, eleman_türü[indeks_türü] şeklindedir. Örneğin türü string olan gün isminden, türü int olan gün sıra numarasına eşleme yapan bir eşleme tablosu şöyle tanımlanır:

    int[string] günSıraları;

Eşleme tablolarının en kullanışlı taraflarından birisi; indeks ve eleman türü olarak, daha sonra öğreneceğimiz yapı ve sınıf türleri de dahil olmak üzere, her türün kullanılabilmesidir.

Dinamik dizilerinki gibi, eşleme tablolarının boyları da tanımlandıkları zaman belirlenmez; tablo, otomatik olarak büyür.

Atama

Elemanı indeks değeri ile atamak; eşleme bilgisinin kurulması ve tablonun otomatik olarak büyümesi için yeterlidir:

    günSıraları["Pazartesi"] = 0;
    günSıraları["Salı"] = 1;
İlkleme

Gün sıraları kavramında olduğu gibi, eşleme bilgisi bazen tablo kurulduğu sırada bilinir. Eşlemeleri teker teker atayarak kurmak yerine, bu bilgiyi tabloyu tanımladığımız zaman da verebiliriz. Tablo, dizi söz diziminde olduğu gibi ilklenir; indeks değerleri ile eleman değerleri arasına : karakteri yazılır:

    int[string] günSıraları =
        [ "Pazartesi":0, "Salı":1, "Çarşamba":2,
          "Perşembe":3, "Cuma":4, "Cumartesi":5, "Pazar":6 ];

    writeln(günSıraları["Salı"]);    // "1" yazar
Eleman silme

Buradaki kullanımında "çıkart, at" anlamına gelen .remove işlevi ile:

    günSıraları.remove("Salı");
    writeln(günSıraları["Salı"]);  // ← çalışma zamanı HATASI

Son satır, tabloda bulunmayan bir elemana eriştiği için çalışma zamanında bir hata atılmasına neden olur.

Eleman sorgulama

Tabloda bulunmayan bir elemana erişmek, bir hata atılmasına neden olacağı için; sorgulamak için in işleci kullanılır. Bu kullanım, "içinde var mı?" sorusunu yanıtlar:

    if ("mor" in renkKodları) {
        // evet, renkKodları'nda "mor" indeksli eleman varmış

    } else {
        // hayır, yokmuş...
    }
Nitelikler
Örnek

Girilen rengin İngilizcesini veren bir program şöyle yazılabilir:

import std.cstream;

void main()
{
    string[string] renkler = [ "siyah"   : "black",
                               "beyaz"   : "white",
                               "kırmızı" : "red",
                               "yeşil"   : "green",
                               "mavi"    : "blue",
                               ];

    dout.writefln("Ben bu ", renkler.length,
                  " rengin İngilizcelerini öğrendim: ",
                  renkler.keys);

    dout.writef("Haydi sor: ");

    char[] türkçesi;
    din.readf(&türkçesi);

    if (türkçesi.idup in renkler) {
        dout.writefln(
            "İngilizce'de \"%s\"", renkler[türkçesi]);

    } else {
        dout.writefln("Onu bilmiyorum...");
    }
}
Problemler
  1. Kullanmakta olduğunuz bir eşleme tablosunu nasıl bütünüyle boşaltabilirsiniz? En az üç yöntem düşünülebilir:
    • bir döngü içinde teker teker silmek
    • boş bir tablo atamak
    • bir öncekine benzer olarak, tablonun .init niteliğinden yararlanmak

      Not: Bu niteliği ilk defa duyuyorsunuz: her türün .init niteliği, o türün ilk değeri olarak kullanılan değerdir; örneğin:
          sayı = int.init;    // int için 0 olur
      
  2. Dizilerde olduğu gibi, eşleme tablolarında da her indekse karşılık tek bir eleman bulunabilir. Baştan bunun kısıtlayıcı olduğu düşünülebilir.
  3. Her öğrenci için birden fazla not tutmak istiyor olalım. Örneğin "emre" için 90, 85, 95, vs. notları barındırmak isteyelim.

    Bir eşleme tablosu kullanmak, notlara notlar["emre"] şeklinde öğrencinin ismiyle erişme konusunda yardımcı olur. Ancak, notları tabloya aşağıdaki şekilde yerleştirmek işe yaramaz:

      int[string] notlar;
      notlar["emre"] = 90;
      notlar["emre"] = 85;   // ← Olmaz: birincinin üstüne yazar
    

    Ne yapabilirsiniz? Her öğrenci için birden fazla not tutabilen bir eşleme tablosu tanımlayın.

... çözümler