February 20, 2012

Ayrıca yeni fikirlerin... :rolleyes:

Bugün (bu yeni haftanın ilk gününün) verimli geçeceğini düşünüyorum. Bağlı listeleri tuttum ve kopartacağım inşaallah...:)

Belki ters bir şeyler yapıyorum diye bellekteki değerlerin kaymasını yukarıdaki (D.ershane'deki) kodlar ile de denedim:

   writeln("Liste\t@", &sayılar, "\t.baş      @", &sayılar.baş);
   writeln("Düğüm\t@", &say, "\t.eleman   @", &say.eleman, "\t.sonraki  @", &say.sonraki);
   sayılar.başınaEkle(10);
   writeln(sayılar);

Yine aynı şey oluyor ki başınaEkle() işlevinden (ilk kurulum dışında) uzak durmamız gerekli diye düşünüyorum. Yoksa yavaş olacağı aşikar öyle değil mi? Çıktısı ise şöyle:

'(9 @BFB49BF0
-> 8 @BFB49B50
-> 7 @BFB49AB0
-> 6 @BFB49A10
-> 5 @BFB49970
-> 4 @BFB498D0
-> 3 @BFB49830
-> 2 @BFB49790
-> 1 @BFB496F0
-> 0 @BFB49650
)
Liste @BFB49DD4 .baş @BFB49DD4
Düğüm @BFB49DCC .eleman @BFB49DCC .sonraki @BFB49DD0
(10 @BFB49BF0
-> 9 @BFB49B50
-> 8 @BFB49AB0
-> 7 @BFB49A10
-> 6 @BFB49970
-> 5 @BFB498D0
-> 4 @BFB49830
-> 3 @BFB49790
-> 2 @BFB496F0
-> 1 @BFB49650
-> 0 @BFB495B0
)'

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 20, 2012
import std.stdio;

struct Dugum
{
   int eleman;
   Dugum * sonraki;

   this(int eleman, Dugum * sonraki)
   {
       this.eleman = eleman;
       this.sonraki = sonraki;
   }
};

void main()
{
   Dugum * basDugum;
   Dugum * yeniDugum;

   basDugum = new Dugum(1, basDugum);

   yeniDugum = new Dugum(2, basDugum);
   basDugum = yeniDugum;

   yeniDugum = new Dugum(3, basDugum);
   basDugum = yeniDugum;


   while (basDugum != null)
   {
       writefln("-> %s", basDugum.eleman);
       basDugum = basDugum.sonraki;
   }
}

Umarım yardımcı olur. Ali'nin örneğini mümkün olduğunca küçültmeye çalıştım. Şu adreste (http://www.zafercelenk.net/post/2009/08/21/Bagl%C4%B1-Listeler-%28Linked-List%29.aspx) benim yazdığım küçük bir yazı ve kodlar var belki fikir verebilir diye ekliyorum.

Diğer taraftan Ali'ninde yazdığı gibi bağlı listeyi mutlaka kağıt üzerinde çalış, hem kendine dönüşlü yapılan yüzünden, hemde göstericilerin adresleri üzerinden takaslar yapıldığı için kodlarla bu yapıyı anlamak zor oluyor. Ama kağıt ve kalemle en fazla 10 dakikada kavrayabileceğin basit bir olay ;-)

Bu arada şöyle bir kodun D karşılığı ne olabilir?

basDugum = (struct dugum *) malloc(sizeof(struct dugum));

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 20, 2012

Teşekküler Zafer, inceleyeceğim...

Alıntı (zafer):

>

Bu arada şöyle bir kodun D karşılığı ne olabilir?

> basDugum = (struct dugum *) malloc(sizeof(struct dugum));
> ```

Bundan sanırım, Ali hoca bahsetmişti ve her şeyi 'new()', dolayısıyla çöp toplayıcı üstleniyormuş. Bu durumda karşılığı şöyle olsa gerek:

dugum* basdugum;
basDugum = cast(dugum*) new dugum(null);


Tabi 'cast()' gereksiz duruyor, D'nin gözünü seveyim bea...:)

Bu arada makaleni okudum ve kutular ile (adresleri ile birlikte) ifade edilen görüntü çok hoşuma gitti. İşte beneklerin (pixel) gücü ama karakterler ile yapılan da çok nostaljik göründüğünü itiraf etmeliyim, yani o da hoş.

Bir kaç deneme yaptım, aslında şu adres olayını kafaya taktım. O yüzden C'ye dönüp çöp toplayıcısı olmayan bir derleyiciye geçmeyi düşünüyorum. Çünkü son aldığım sonuç beni bir kere daha şaşırttı. Şöyle ki; Zafer'in makalesindeki kutularda yer alan adreslerden, acaba bir sonrakinin adresini ekrana yazdırıp yazdıramayacağımı merak ettim. Gel gör ki belleğin çok farlı bölgelerinden şeyler ekrana gelince vaz geçtim. Bakınız:

'AĞAÇdakiler~~~~~v
0	@BFE5FF04
1	@BFE5FE64
2	@BFE5FDC4
3	@BFE5FD24
AĞAÇ	@BFE5FF8C	.yaprak   @B7673FF0	.sonrakiDal  @B7673FF4
AĞAÇ	 B7673FF0	.yaprak    0		   .sonrakiDal   B7673FB0'

Son iki satırın kodu ise şu:

writeln("AĞAÇ\t@", &soy, "\t.yaprak @", &soy.yaprak, "\t.sonrakiDal @", &soy.sonrakiDal);
writeln("AĞAÇ\t ", soy, "\t.yaprak ", soy.yaprak, "\t\t.sonrakiDal ", soy.sonrakiDal);



-- 
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]
February 20, 2012

Alıntı (zafer):

>

Şu adreste (http://www.zafercelenk.net/post/2009/08/21/Bagl%C4%B1-Listeler-%28Linked-List%29.aspx) benim yazdığım küçük bir yazı ve kodlar var belki fikir verebilir diye ekliyorum.

Güzelmiş! :)

Alıntı:

>

Bu arada şöyle bir kodun D karşılığı ne olabilir?

> basDugum = (struct dugum *) malloc(sizeof(struct dugum));
> ```


Salih'in gösterdiği gibi new() olur ama tam karşılığı olmuyor tabii ki çünkü malloc() ilklenmemiş çiğ bellek ayırır. new() ise ayırdığı bellek üzerinde kullanıma hazır bir nesne oluşturur.

D'de de boş bellek ayrılabiliyor ama önemli sakıncaları ve kuralları var. Benim bildiklerim şurada yazılı:

 http://ddili.org/ders/d/bellek_yonetimi.html

Özellikle "Bellekten yer ayırmak" başlığı altında C'nin malloc()'unun kullanımı bile var.

Ali

-- 
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]
February 20, 2012

Alıntı (acehreli):

>

D'de de boş bellek ayrılabiliyor ama önemli sakıncaları ve kuralları var. Benim bildiklerim şurada yazılı:

http://ddili.org/ders/d/bellek_yonetimi.html

Özellikle "Bellekten yer ayırmak" başlığı altında C'nin malloc()'unun kullanımı bile var.

D dilinde bellek ayırma işlemini bir yerde gördüğüm aklımdaydı ama nerede olduğunu bir türlü hatırlayamamıştım :) Nerede gördüğümü şimdi anladım :)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 21, 2012

Peki D dilinde listelere ekleme yapıp çıkarmak için method'lar yok mu? C#'da inanılmaz çok örnek ile karşılaştım. Gerçi bir sürü ekleme ve çıkarma komutuyla işi iyice karıştırmışlar...:)

Kolaylıkları da yok değil hani. Mesela listeyi şöyle tek satırda, verileri ile birlikte kurabiliyormuşuz:

LinkedList<int> primes = new LinkedList<int>(new int[] { 3, 5, 7, 11, 15, 17 });

Çıkarmaya iki method var ki ilki herkesin aklına gelen: primes.Remove(15); şeklinde...

Diğer yöntem primes.RemoveAt(1) ki bu ikinci elemanı çıkar demek. (-bknz. <www.dotnetperls.com/list-remove>)

Eklerken, teker teker (sadece Add ile) sıralı bir şekilde, başa ve sona olmak üzere üç etti. Bir de bulduktan sonra AddAfter() toplam da dört tane var:

primes.Add(2);
primes.Add(3);
primes.Add(5);
: : :

Sık kullanılanlar ise şunlar:

primes.AddFirst(2);
primes.AddLast(19);

İçlerinden birini arayacağımızda biraz uzun, LinkedListNode<int> node = primes.Find(11); şeklinde.

Hemen dördüncü ekleme komutuyla biraz işi kolaylaştırmışlar:

primes.AddAfter(node, 13);

Böylece elde ettiğimiz düğümü kullanarak araya ekliyor. Gerçi bunların temeli iki üç komut çünkü bir insert (node, item) komutu var; herhalde eklemelerin temeli budur. Ama gel gelelim ben overload olduğundan çalıştıramadım... :blush:

Sanırım boş düğüm olması gerekiyor ve oraya giriyor ya anlamadım. Neyse sonuçta biz D'yi konuşuyoruz ama bunları yaparsak 10 numara olacak.

Başarılar...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 21, 2012

D'de şimdilik tek-bağlı liste olarak SList var:

http://dlang.org/phobos/std_container.html#SList

En yakın karşılığı şu program olabilir:

import std.stdio;
import std.container;

void main()
{
   auto primes = new SList!int(1, 2, 3, 4, 5);

   primes.removeFront();

   primes.insert(10);
   primes.insert(11);
   primes.insertFront(12);
   primes.insertAfter(primes.opSlice(), 13);

   writeln(primes.opSlice());
}

'[12, 11, 10, 2, 3, 4, 5, 13]'

Belirli bir konumdaki elemanı çıkartma işlemi yok. (Zaten bağlı listeye uygun bir işlem değil.) find() gibi işlevleri de topluluklar üzerinde değil, algoritmalar olarak isteriz. Daha kullanışlıdır. D'de şöyle:

import std.algorithm;
// ...
   writeln(find(primes.opSlice(), 4));

Çıktısı:

'[4, 5, 13]'

Çünkü find(), aralığın bulduğu noktadan sonrasını yine bir aralık olarak verir. Bulunan elemanı kullanmak istediğimizde sonuç.front deriz.

Evet, opSlice() çağrısının gerekmesi çok saçma. Kısaca primes[] yazabilmeliydik. std.container'ı iyi bilmiyorum; şimdilik daha fazla kurcalamayacağım. :)

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 22, 2012

Alıntı (Ali Çehreli):

>

D'de şimdilik tek-bağlı liste olarak SList var:

http://dlang.org/phobos/std_container.html#SList
Vaoov...:)

Bunu öğrendiğim çok çok iyi oldu, teşekkürler...

Hemen inceliyorum hatta dayanamadım iletiyi okurken kodlarına baktım da yapıyı şu şekilde oluşturmuşlar:

struct SList(T) {
   private struct Node {
       T _payload;
       Node * _next;
       this(T a, Node* b) { _payload = a; _next = b; }
   }
   private Node * _root;

   private static Node * findLastNode(Node * n) {
       auto ahead = n._next;
       while (ahead) {
           n = ahead;
           ahead = n._next;
       }
       return n;
   }
: : :

Devamı... (satır 852) (https://github.com/D-Programming-Language/phobos/blob/master/std/container.d#L852)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 23, 2012

Merhaba,

Bugün, geçen hafta sonundan beri (sizler sayesinde) öğrendiğim bağlı liste (aslında 1978'de C'nin 2. sürümüne eklenen struct kavramının birbirlerine bağlı haliymiş: Linked List) olayını pekiştirmeye çalışıyorum...

Zafer'in, önceki sayfada yer alan temiz çözümü (clear~simple~solution) beni bir adım daha ileriye götürdü. Kendisine özellikle teşekkür ederim. Bu konuları araştırdıkça, aslında 1955'e değil benim ana karnında olduğum (1978-1979) zamana denk geldiğini öğrendim. Bu da benimle yaşıt olması anlamına geliyor ki manevi açıdan adeta gazlıyor! Düşünsenize, 30'lu yaşlarımdayım ve henüz yeni öğreniyorum: aaa çok büyük ayıp!...:)

Şaka bir yana, sormak değil öğrenmemek ayıpmış. Ancak şimdi tek bir soru dışında (-bknz. sondaki yıldızlı parantez) sorular ile daha çok başınızı şişirmek istemiyorum. Adım adım, öğrendiklerimi pekiştirmek için yaptığım son denemeleri aşağıda izleniminize sunmalıyım:

  • İlk olarak anlayışı kolaylaştırmak için herkesin bildiği atom modelini temel aldım. Her şeyi en basit şekilde anlamam gerektiği için yapıyı da olabildiğince basit (sadece 3 satır!) oluşturdum:
/*
atom.d (23.02.2012)
*/
import std.stdio;

struct Atom {
   Atom* element;          // Eğer adres değeri F70 ile bitiyorsa,
   ubyte proton;           // 2. eleman türden bağımsız F74 oluyor

   this(Atom* a, ubyte b) { element = a, proton = b; }
}

void main () {
   Atom* baştaki, sonraki = new Atom(null, 1);    // Hidrojen (en basit element!)
   // Yukarıda, kurulum ve ilk değerin (düğümün~node) eşitlenmesi yapılmaktadır,
   // sonraki'den kasıt, etkin olan değer(ler)i yani düğümü ifade eder...

   foreach(ubyte atomNumarası; 2..4) {
       baştaki = new Atom(sonraki, atomNumarası);
       sonraki = baştaki;
   } do {
       writeln(&sonraki.proton, " -> ", sonraki.proton,
                                "@", &sonraki.element);
       sonraki = sonraki.element;
   } while(sonraki != null);
}

Çıktısı:
'B7781F74 -> 3@B7781F70
B7781F84 -> 2@B7781F80
B7781F94 -> 1@B7781F90'

  1. Fakat teknik nedenlerden dolayı veri, tersten (-bknz. yukarıdaki çıktı) birbirlerine bağlanıyordu. Hem bunu düzeltmek, hem de 'main()' içindeki kodlamayı basitleştirmek için yapıyı şöyle oluşturabiliriz:
struct Atom {
   Atom* element;          // Eğer adres değeri F70 ile bitiyorsa,
   ubyte proton;           // 2. eleman türden bağımsız F74 oluyor

   this(Atom* a, ubyte b) {
       this.element = a;
       this.proton = b;
   }

   void atomuEkle(ref Atom* sonraki, ubyte değeri) {
       auto ekle = new Atom(null, değeri);
       sonraki.element = ekle;
       sonraki = ekle;
   }

   string toString() const {
       string tamamı = format("%X -> %d", &proton, proton);
       if (element) tamamı ~= "\n" ~ to!string(*element);

       return tamamı;
   }
}

Satır sayısı arttığı için her şeyi yaydım tabi...:)

Özellikle, 'this{}' kümesi içindeki özdeğişkenlerin başına tekrar this ifadesi kullanmak gerekmediğini bildiğim halde, bunun da olabileceğini göstermek için ifade etmekten kaçınmadım. Aslında satırları katık etmeyi (idareli kullanmayı) severim; böylece tek sayfada görüntüleyebileceğim satır sayısı fazla olduğundan, hakimiyeti (bu bana özel ve standartların dışında!) arttırabiliyorum.

Artık, birini (*) saymazsak sadece iki satır ile sonucu düzgün bir şekilde yansıtabiliyoruz:

import std.stdio, std.conv, std.string;   // 2 sınıf daha eklemeliydik!

// main();
: : :

   foreach(ubyte atomNumarası; 2..4) sonraki.atomuEkle(baştaki, atomNumarası);
   writeln(to!string(*sonraki));
}

Çıktısı:
'BFC4F774 -> 1@BFC4F770
BFC4F6D4 -> 2@BFC4F6D0
BFC4F634 -> 3@BFC4F630'

(*) Eğer 'foreach()' önüne yapının kopyasını birbirine eşitlemezseniz (baştaki = sonraki;) çalışma zamanı hatası verecektir!

Neden?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 23, 2012

Ali Hocam, geçen hafta verdiğin aşağıdaki cevabı yeni gördüm...

Bu olsa olsa geleceğe gönderilen cevap olur...:-D

Alıntı (Ali Çehreli:1329670927):

>
>     void başınaEkle(int eleman)
>     {
>         baş = new Düğüm(eleman, baş);
>     }
> ```

> Şöyle daha açıklayıcı olabilirdi:
>
>
void başınaEkle(int eleman)
{
    Düğüm * yeniDüğüm = new Düğüm(eleman, baş);
    baş = yeniDüğüm;
}
>

Alıntı:

>

Gerçi hayatta bir çok şey tersine işler (burada verilerin ters belleğe yerleşmesi gibi)
Burada bağlı listenin ters oluşmasının tek nedeni, Liste'nin basitliği. Yoksa 'son' diye bir gösterge de barındırabilir ve yeni düğümü ona bağlayabilirdir. Veya hızdan ödün vererek baştan başlayarak sonuncu düğümü bulurdu ve oraya ekleyebilirdi.
Tek farkı tersten eklemesi! Bu kodu, şimdi, şu şekilde denedim:

// struct Atom {}
   void başınaEkle(ubyte değeri) {
       Atom* yenibirAtom = new Atom(element, değeri);
       element = yenibirAtom;
   }
// main ()
   //baştaki = sonraki;
   foreach(ubyte atomNumarası; 2..4) {
       //sonraki.atomuEkle(baştaki, atomNumarası);/*
       sonraki.başınaEkle(atomNumarası);//*/
   }

Böylece "Neden?" sorusuna (kısmen) cevap verilmiş oldu. Bunun daha zarif göründüğünü söylemeliyim...:)

Teşekkürler...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]