Forum: Ders Arası RSS
Erişicilerle aralıkların karşılaştırılması
canalpay (Moderatör) #1
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Daha güzel sorular sormamak için kendimi zor tutuyorum : (Tutamadım :-) )

Örneğin range olsun erişici olsun tam olarak ne demektir.

Benim bildiğim erişici hiç bilmediğim C(yada c++) kodunda gördüğüm c.begin gibi dizilerde kullanılarak ilk eleman olsun son eleman olsun öğrenmeye yarayan bir araç ?

Benim bildiğim range ise : dizi[0..11] şeklinde ulaşım ?

Rangenin sağladığı ne şimdi ? Diyeceksiniz ki Andrei'nin makalesini oku. Ancak biraz üst düzey olduğu için biraz daha temelini öğrenmek istedim.
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Çok kısaca... :)

Yalnızca dizi ve bağlı liste topluluklarını ele alalım. Belirli numaralı bir dizi elemanına erişim için [] işleci kullanılır. Bağlı listede ise başından o numaraya kadar ilerlemek gerekir.

Algoritma olarak da "şu aralıktaki elemanları rastgele karıştır" anlamına gelen karıştır diye bir algoritma düşünelim.

Erişici diye bir kavram olmasa, ancak bütün topluluğu karıştırabiliriz. Ek olarak, dizi karıştırma ve bağlı liste karıştırma algoritmalarını farklı farklı yazmak zorunda kalırız.

Erişiciler (iterator), algoritmalarla toplulukları birbirlerinden soyutlarlar. karıştır, baş tarafı ve sonu belirleyen iki erişici alacak şekilde tasarlarsak, topluluğun kendi içindeki belirli bir aralığı bile karıştırabiliriz:

// Hepsini değil, ortasını karıştır
karıştır(dizi.begin() + 3, dizi.end() - 5);
 
// Aynı algoritma liste için de çalışır
karıştır(liste.begin() + 3, liste.end() - 5);

(Aslında liste için perde arkasında daha hızlı başka algoritma kullanılıyor da olabilir ama kullanıcı kodu açısından aynı şekilde yazılır.)

Erişicilerin yararı o...

Aralıklar (range) yalnızca 0..10 gibi sayı aralıkları değil, bir topluluğun belirli bir eleman aralığı anlamına geliyor.

Aralıklar, aslında perde arkasından o iki erişinin bir araya gelmesinden başka bir şey değildir. Aralık kullanan karıştır işlevi şöyle yazılabilir:

karıştır(istediğim_dizi_aralığı);
karıştır(istediğim_liste_aralığı);

İki erişici bir araya gelince, artık algoritmalardan aralıklar döndürülebiliyor. (İşlevlerin tek dönüş değeri olabildiği için iki erişici döndüremezler.) Böylece algoritmalar lego parçaları gibi birbirlerine bağlanabiliyorlar.

Temelde o... :)

Ali
canalpay (Moderatör) #3
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Teşekkürler. İsterseniz yeni bir başlığa aktaralım bu yazıyı.

Ancak benim anlamadığım bazı şeyler var.

Aralıklar (range) yalnızca 0..10 gibi sayı aralıkları değil, bir topluluğun belirli bir eleman aralığı anlamına geliyor.

Bu ne demek ? dizi[3..5] bir topluluğun belirli  bir eleman aralığı değil mi ? [aralık için buraya sayıdan başka ne gelebilir ?]

karıştır(istediğim_dizi_aralığı);
karıştır(istediğim_liste_aralığı);

Burdaki "istediğim_dizi_aralığı" nasıl bir değer taşıyor ?

İşlevlerin tek dönüş değeri olabildiği için iki erişici döndüremezler.)


Bu ne demek ? Erişici neden döndürülsün ki ? Belirli bir eleman  aralığı döndürülmüyor mu ?
acehreli (Moderatör) #4
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
canalpay:
Ancak benim anlamadığım bazı şeyler var.

Bu kadar kısa zamanda yazılmış olan bu kadar kısa bir yanıttan her şeyi anlamadığın için teşekkürler. ;)

Aralıklar (range) yalnızca 0..10 gibi sayı aralıkları değil, bir topluluğun belirli bir eleman aralığı anlamına geliyor.

Bu ne demek ? dizi[3..5] bir topluluğun belirli  bir eleman aralığı değil mi ? [aralık için buraya sayıdan başka ne gelebilir ?]

Toplulukların belirli bir aralığındaki elemanları ifade etmek için indeks değerleri kullanmak her veri yapısına uymaz. Örneğin bağlı listenin "yüzüncü elemanından bininci elemanına kadar" demek için erişicileri başından başlayarak o kadar kere yürütmek gerekir. Aynı şey ikili ağaç yapılarında veya başka yapılarda da vardır.

D'nin desteklediği iki adet veri yapısı var: dizi ve eşleme tablosu. Her ikisi de rahatça indekslendiği için her veri yapısında da öyle olacağını düşünüyoruz. Daha onlarca başka veri yapısı (topluluk) var ve hepsinin özellikleri farklı.
karıştır(istediğim_dizi_aralığı);
karıştır(istediğim_liste_aralığı);

Burdaki "istediğim_dizi_aralığı" nasıl bir değer taşıyor ?

Örneğin şöyle kurulmuş olabilir:

intAralığı istediğim_dizi_aralığı(dizi.begin() + 1, dizi.end() - 1);

İşlevlerin tek dönüş değeri olabildiği için iki erişici döndüremezler.)

Bu ne demek ? Erişici neden döndürülsün ki ? Belirli bir eleman  aralığı döndürülmüyor mu ?

Belirli bir aralıkta bir arama yapıldığında, bulunan elemana erişici döndürülebilir. Başka algoritmalar da erişici döndürebilirler. Örneğin bir ikili ağaç yapısına eleman ekleyince yeni eklenen elemana referans olan bir erişici döndürülür, vs.

Aralık kullanan algoritmalar tek bir erişici değil, bir aralık döndürünce başka algoritmaların parametreleri olabiliyorlar:

writeln(ikiyle_çarp(çift_değerlileri_bul(benim_aralık)));

Orada çift_değerlileri_bul bir aralık döndürebiliyorsa, ikiyle_çarp'ın parametresi olarak kullanılabiliyor.

Eğer her ikisi de baş ve son erişicileri kullansaydı, ancak şöyle yazabilirdik:

BirDizi çift_değerliler = çift_değerlileri_dizi_olarak_döndür(benim_aralık);
writeln(ikiyle_çarp(çift_değerliler.begin(), çift_değerliler.end()));

Ali
canalpay (Moderatör) #5
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Çoğu şeyi anladım teşekkürler.

Kısaca aralık erişiciyi daha iyi kullanabilmek adına programlama dillerine yeni bir yorum diyebiliriz sanırım. (Devamı andreinin makalesinde sanırım :-) )

Acaba D'de normal erişicileri nasıl kullanabiliriz ?
Şöyle bir şeyi nasıl diyebiliriz ? :
    int[] dizi=[1,2,2];
    writeln(dizi[].begin());

Çünkü erişicileri kodsal görünüşlerini çok seviyorum :-)
acehreli (Moderatör) #6
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
canalpay:
Kısaca aralık erişiciyi daha iyi kullanabilmek adına programlama dillerine yeni bir yorum diyebiliriz sanırım.

Erişici de aralık da dilden bağımsız bir kavram. Kütüphanelerle ilgili. C++'nın standart kütüphanesi, erişicilerin en güzel örneği olan STL'i kabul etmiştir. D'nin Phobos'u da aralıkları kabul ediyor.

Acaba D'de normal erişicileri nasıl kullanabiliriz ?

Erişiciler Phobos'tan yavaş yavaş azalacaktır. std.iterator modülünde STL'in eşi olacağı yazıyor ama yakında emekli olacaktır. (Öyle bir şey duymadım; aralıklara verilen öneme bakarak söylüyorum.)

Şöyle bir şeyi nasıl diyebiliriz ? :
    int[] dizi=[1,2,2];
    writeln(dizi[].begin());

import std.stdio;
import std.iterator;
 
// Erişici kullanan bir algoritma
Erişici çiftOlanİlkiniBul(Erişici)(Erişici baş, Erişici son)
{
    for ( ; baş != son; ++baş) {
        if ((*baş % 2) == 0) {
            return baş;
        }
    }
 
    // Bulunamazsa, geleneksel olarak aralığın sonu döndürülür
    return son;
}
 
void main()
{
    int[] dizi=[1, 2, 2];
    writeln("başı: ", dizi.begin());
    writeln("sonu: ", dizi.end());
 
    auto erişici = çiftOlanİlkiniBul(dizi.begin(), dizi.end());
 
    if (erişici != dizi.end()) {
        // bulunmuş
        writeln("ilk çift olan: ", *erişici);
    } else {
        writeln("bulunamadı");
    }
}

Ali
canalpay (Moderatör) #7
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Teşekkürler. Herhalde bunu aralık ile nasıl yazarız dememeliyim.
acehreli (Moderatör) #8
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Diziler otomatik olarak aralık olarak kullanılabildikleri için, ve std.algorithm aralıklarla çalıştığı için çok kolay:

import std.stdio;
import std.algorithm;
 
void main()
{
    int[] dizi=[1, 2, 2];
 
    auto sonuç = find!"(a % 2) == 0"(dizi);
 
    if (!sonuç.empty()) {
        writeln("ilk çift olan: ", sonuç.front());
        writeln("ilk bulunan eleman ve gerisi: ", sonuç);
    } else {
        writeln("bulunamadı");
    }
}

Ali
canalpay (Moderatör) #9
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Teşekkürler.

Gerçekten çok farklı ve güzel gözüküyor.(Her ne kadar string biçimde yani tırnak arasında kod yazımından hoşlanmasamda. find gibi :-) )

Ayrıca sanırım kodunuzda std.range'yi eklemeyi unutmuşsunuz. Eklemeyince .empy ve .front hakkında hata veriyor.
acehreli (Moderatör) #10
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
std.range dışarıda kalmış. :)

find'ın karar işlevi (predicate) alanı da var:

import std.range;
import std.stdio;
import std.algorithm;
 
bool çift_mi(int sayı)
{
    return (sayı % 2) == 0;
}
 
void main()
{
    int[] dizi=[1, 2, 2];
 
    auto sonuç = find!çift_mi(dizi);
 
    if (!sonuç.empty()) {
        writeln("ilk çift olan: ", sonuç.front());
        writeln("ilk bulunan eleman ve gerisi: ", sonuç);
    } else {
        writeln("bulunamadı");
    }
}

Ali
canalpay (Moderatör) #11
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Bu arada phobos'un svn deposuna std.iterator kaldırıldı ve belgeleri derlemeden çıkarıldı. Ayrıca not olarak zaten 8 Hazirandan beri phobos'un inşasına eklenmiyordu denmiş. Ali Beyin dediği gibi oldu ve D artık daha çok aralık kullanmaya ve desteklemeye başladı ve erişicilere desteğini kesmeye başladı.
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Forum: Ders Arası RSS
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-23, 23:24:35 (UTC -08:00)