February 20, 2012

Alıntı (Salih Dinçer):

>

Belki seni çok basit konularda meşgul ediyoruz.

Kimse mecbur olmadığına göre buraya bir şey yazıyorsam kendi isteğimle yazıyorum. Meşgulsem yazmam ve zaten zaman bulana kadar da yazmıyorum. :)

Alıntı:

>

O yüzden hakkını helal et lütfen... :blush:

Ettim! Sen de benim yanıt yazarken öğrendiklerim için hakkını helal et.

Söz zaman kaybından açılmışken, zaman kaybını azaltmamızın bir yolu, tam olarak hangi programın kullanıldığını göstermek olur. ;) Deminden beri diğer konudaki programını buradaki bilgilerle değiştirerek seninle aynı sonucu almaya çalışıyorum. :)

Yer sorunumuz yok, konu adedi sorunumuz yok, hiçbir sorunumuz yok. :) Hatta ben olsam bu soruyu ayrı bir konu olarak açardım çünkü burada çok özel bir konuya geçtik: Neden gösterge değerleri beklediğimiz gibi çıkmıyor.

Teşekkürler, ;)
Ali

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

February 21, 2012

Sanırım dizi konusunu güzel bilgiler öğrenerek kapattık. Bağlı liste konusunda aslında Ali'ninde belirttiği gibi SList'i kullanabiliriz.

Ancak madem amacımız öğrenmek o zaman kendimiz küçük bir liste yazalım diye düşündüm ve elemanları sıralı olarak ekleyen şöyle basit bir liste hazırladım. Devamını hep beraber getiririz artık :-D

import std.stdio;
import std.random;

struct Dugum
{
   int eleman;
   Dugum * sonraki;

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

void main()
{
   Dugum * basDugum;

   for (int i = 0; i < 100; ++i)
   {
       ListeyeEkle(basDugum, uniform(0, 100));
   }

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

void ListeyeEkle(ref Dugum * ilkDugum, int eleman)
{
   Dugum * gecerliDugum = ilkDugum;
   Dugum * oncekiDugum;

   Dugum * yeniDugum = new Dugum(eleman, null);

   while (gecerliDugum != null && gecerliDugum.eleman < eleman)
   {
       oncekiDugum = gecerliDugum;
       gecerliDugum = gecerliDugum.sonraki;
   }

   if (oncekiDugum == null)
   {
       ilkDugum = yeniDugum;
   }
   else
   {
       oncekiDugum.sonraki = yeniDugum;
   }

   yeniDugum.sonraki = gecerliDugum;
}

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

February 21, 2012

Çok çok teşekkürler Zafer, bunu anlıyor gibiyim çünkü ifadeler Pandora'nın kutusunda (yapı~struct) içinde olmayınca sanki daha anlaşılır geliyor. Tabi Ali hocanın yaptığı daha leziz bir çözüm gibi görünüyor. Hatta @property gibi ek özellikler ekledik mi sanırım çok kullanışlı bir liste yapılır. Neyse...

Yukarıdaki yazdıklarım yorum yani iltifat. Hiç yazmadım da farz edebilirsiniz. Çünkü hala an-la-ya-mı-yo-rum...:(

Örneğin anlamak için yukarıdaki kodun çıktısını şu şekilde işlettim:

   //for (int i = 0; i < 10; ++i) ListeyeEkle(basDugum, uniform(0, 10));/* Rasgele
   foreach(i; 0..10) ListeyeEkle(basDugum, i);//*/
   while (basDugum != null)
   {
       writefln("@%x-> %s", &basDugum.eleman, basDugum.eleman);
       basDugum = basDugum.sonraki;
   }

Aslında gizlenen satırı da sayarsak, iki şekilde de (biri rasgele) denememe rağmen yine anlamadım! Eğer "@%x->" ile ifade ettiğim adres değerleri yine gerçeği yansıtmıyorsa bu yazdıklarımı da hiç yazmadım farz edin. Ama bunlar verinin bulunduğu gerçek adresler ise rasgele ile sıralı veri geçirmede ki farklılığın sebebi nedir? İşte çıktıları...

Rasgele:
'@b77c2f10-> 0
@b77c2ee0-> 4
@b77c2ef0-> 4
@b77c2ec0-> 5
@b77c2ed0-> 6
@b77c2f50-> 6
@b77c2f00-> 7
@b77c2f30-> 7
@b77c2f40-> 7
@b77c2f20-> 8'

Sıralı:
'@b7794f50-> 0
@b7794f40-> 1
@b7794f30-> 2
@b7794f20-> 3
@b7794f10-> 4
@b7794f00-> 5
@b7794ef0-> 6
@b7794ee0-> 7
@b7794ed0-> 8
@b7794ec0-> 9'

Dikkat ederseniz sıralı verilerin kayıt edildiği çıktıda verilerin arası tam hex 1 byte, yani mesafeler eşit. Rasgelede ise artık ne oluyorsa oralarda kafasına göre takılmış...:)

Sevgiler, saygılar...

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

February 21, 2012

Alıntı (acehreli):

>

Zafer'in oradaki programındaki ListeyeEkle()'nin sıralı olarak eklediğini farkediyorsun, değil mi?
Evet, fark etmiştim ve bugün, sağ olsun Zafer'in kodları ile çalıştım. Açıkçası D.ershane'deki çift struct çok kafamı karıştırdı. Şimdi Mono ile C#'a geçtim ve karşılaştırma yapıyorum. Bunu yaparken de ekle(), ara() ve sonaEkle() method'larını yapmaya çalışacağım. Çünkü şu sitenin ilgili dersinde bunlar hali hazırda gelmiş:

http://www.dotnetperls.com/linkedlist

Böylece aratabilirsek, araya ekleme yapıp tıpkı daha önce bu başlıkta dizilere uyguladığımız gibi bir sıralama olayını deneyebiliriz. En son da binlerce değer ile test etmeliyiz. Bakalım hangisi verimli çıkacak...:)

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

February 21, 2012

Alıntı (Salih Dinçer):

>

'
@b7794ed0-> 8
@b7794ec0-> 9'

Dikkat ederseniz sıralı verilerin kayıt edildiği çıktıda verilerin arası tam hex 1 byte, yani mesafeler eşit.

Mesafelerin eşitliği tesadüf. Başka bir programda belleğin daha ayrık yerlerinde de olabilirlerdi. Ama araları da aslında 0x10, yani 16 bayt.

Alıntı:

>

Rasgelede ise artık ne oluyorsa oralarda kafasına göre takılmış...:)

Zafer'in oradaki programındaki ListeyeEkle()'nin sıralı olarak eklediğini farkediyorsun, değil mi? O programa iki writefln ekledim.

  1. main'in sonundaki while döngüsünün içine:
   while (basDugum != null)
   {
       writefln("-> %s (%s)", basDugum.eleman, basDugum); // <-- ALİ
       basDugum = basDugum.sonraki;
   }
  1. ListeyeEkle()'nin en son satırı olarak:
   writefln("Yeni düğümü %s (%s) %s (%s) düğümünden önceye ekledim", // <-- ALİ
            yeniDugum.eleman,
            yeniDugum,
            yeniDugum.sonraki ? yeniDugum.eleman : -1, // null için öylesine -1
            yeniDugum.sonraki);

Çıktısı bana mantıklı geliyor:

'Yeni düğümü 24 (2AEB8E9EFFE0) -1 (null) düğümünden önceye ekledim
Yeni düğümü 85 (2AEB8E9EFFC0) -1 (null) düğümünden önceye ekledim
Yeni düğümü 62 (2AEB8E9EFFA0) 62 (2AEB8E9EFFC0) düğümünden önceye ekledim
Yeni düğümü 79 (2AEB8E9EFF60) 79 (2AEB8E9EFFC0) düğümünden önceye ekledim
Yeni düğümü 46 (2AEB8E9EFF40) 46 (2AEB8E9EFFA0) düğümünden önceye ekledim
Yeni düğümü 5 (2AEB8E9EFF20) 5 (2AEB8E9EFFE0) düğümünden önceye ekledim
Yeni düğümü 62 (2AEB8E9EFF00) 62 (2AEB8E9EFFA0) düğümünden önceye ekledim
Yeni düğümü 95 (2AEB8E9EFEE0) -1 (null) düğümünden önceye ekledim
Yeni düğümü 80 (2AEB8E9EFEC0) 80 (2AEB8E9EFFC0) düğümünden önceye ekledim
Yeni düğümü 75 (2AEB8E9EFEA0) 75 (2AEB8E9EFF60) düğümünden önceye ekledim
-> 5 (2AEB8E9EFF20)
-> 24 (2AEB8E9EFFE0)
-> 46 (2AEB8E9EFF40)
-> 62 (2AEB8E9EFF00)
-> 62 (2AEB8E9EFFA0)
-> 75 (2AEB8E9EFEA0)
-> 79 (2AEB8E9EFF60)
-> 80 (2AEB8E9EFEC0)
-> 85 (2AEB8E9EFFC0)
-> 95 (2AEB8E9EFEE0)
'

Sayılar sıralı olarak doğru yerlere eklenmişler ve new ile oluşturulduklarında bildirilen adresler son listede de görünüyorlar.

Ali

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

February 21, 2012

Alıntı (Salih Dinçer):

>

D.ershane'deki çift struct çok kafamı karıştırdı.

Yani Düğüm ve Liste yapıları, değil mi. Tamam, şimdilik yalnızca Düğüm'le devam et. Liste'nin daha yararlı olduğunu sonra kabul edersin. ;) Liste gibi farklı bir yapı senin gösterdiğin bir pdf'in "Other Implementations" başlığı altında da geçiyor:

Alıntı:

>

• Head struct A variant I like better than the dummy header is to have a
special "header" struct (a different type from the node type) which
contains a head pointer, a tail pointer, and possibly a length to make many
operations more efficient. Many of the reference parameter problems go
away since most functions can deal with pointers to the head struct
(whether it is heap allocated or not). This is probably the best approach to
use in a language without reference parameters, such as Java.

Baş, son, uzunluk, vs. gibi düğümlerle değil, liste kavramı ile ilgili olan değişkenlerin "başlık" gibi bir yapıya alındıklarını söylüyor. Yani benim Liste...

Düğüm gibi tek yapı da olur ama tam soyutlamayı vermez. Çünkü örneğin yukarıdaki yazıdaki gibi 'son' diye bir gösterge de olsa, bu sefer kullanıcılar 'baş' ve 'son' diye ayrık iki gösterge yoluyla mı kullanacaklar. Liste olursa bütün bu ayrıntıları onun içine yerleştiririz ve kısaca liste.başınaEkle(1), liste.sonunaEkle(2), vs. diyebiliriz.

Ali

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

February 24, 2012

Arkadaşlar, gerçekten de Linked List'ler çok hantalmış.
Aşağıdaki kodu siz de dener misiniz; ben 6 kat fark gördüm!

10 Elemanlı Çıktısı:
'[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Vector List
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) Linked List'

/*
listsTest.d (24.02.2012)
*/
import std.array, std.conv, std.random, std.range, std.string, std.stdio;

struct Node {
   int data;
   Node* tail;

   this(int d, Node* t) { data = d; tail = t; }

   string toString() const {
       string result = to!string(data);
     if(tail) result ~= ", " ~ to!string(*tail);

       return result;
   }
}

void sequentialAdd(int value, ref Node* head) {
   Node* previous, current = head;
   Node* next = new Node(value, null);

   while(current != null && current.data < value) {
       previous  = current;
         current = current.tail;
   }

   if(previous == null) head = next;
          else previous.tail = next;

                   next.tail = current;
}

void sequentialAdd(int d, ref int[] a){
   uint k;
   auto app = appender!(int[])();

   for(k = 0; k < a.length; k++) if(d < a[k]) break;
   app.put(a[0 .. k]);
   app.put(d);
   app.put(a[k .. $]);
   a = app.data;
}

void main() {
   Node* testList;
   int[] testArray;// = [uniform(0, 9)];
   int[] numbers = [ 1, 3, 5, 7, 9, 8, 6, 4, 2, 0 ];
   auto rnd = Random(unpredictableSeed);

   for(uint test = 10; test <= 9999; test++) numbers ~=  uniform(0, 100);

   foreach(int number; randomCover(numbers, rnd))
       sequentialAdd(number, testArray);//testList);

   //writefln("(%s) Linked List", to!string(*testList));/*
   writeln(testArray, " Vector List");//*/

   /* Processing Time (Intel Atom N450 CPU):
      Vector List ~ 6 seconds!
      Linked List ~ 36 seconds!
   */
}

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

February 24, 2012

Alıntı (Ali Çehreli):

>
> struct Node {
>     int data;
>     Node* next;
> }
>
> struct List {
>     Node* head;
>     Node* tail;
> }
> ```

> Düğümün içindekine 'tail' deyince ve liste ile bu kadar yakın bir kavram olunca kafa karıştırma tehlikesi var.
Haklısın Ali Hocam, özellikle İngilizce ifadelerde daha fazla yanlış yapabiliyorum. Sonuçta bu kendi dilim değil ama Atom yani proton ve element ikilisi nasıldı? Sanırım buna itirazın yok...:)

Üstelik bu terimleri elin yabancısı da anlar, İngilizce bilmeyen ilkokula giden lazı da. Bu arada 'tail'in tam Türkçe karşılığı olarak kuyruk deyip geçmek yanlış değil mi? Bir listenin küçük bir parçası gibi değerlendirmeli. Yoksa yazıcı kuyruğu dendiği zaman tam karşılık olarak "printer queue" yazılır ya.

Sevgiler, saygılar...

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

Alıntı (Ali Çehreli):

>

Ekrana yazmayı dahil etmiyorsun, değil mi? Ben onu çıkarttıktan sonra her ikisi de 1.8 saniye sürdü. Fark görebilmek için 10 binden daha fazla elemanla denemek gerekiyor.
Pardon, sonuçları o kadar çok merak ediyordum ki sonucu etkileyen şeyleri ihmal etmişim! Bu durumda tostring() ifadesiyle ekrana yazma yöntemi en fazla 6 kat yavaş olduğu söylenebilir. Belki bu başka bir teknikle hızlandırılabilir ama aynı ekranın önbelleğini kullandığına göre veriyi tek bir dizge (string) üzerinde birleştirmek, (çünkü o da bir dizi) en az 2 kat daha yavaş olacağı aşikar.

Ancak tek çekirdekli yavaş bir işlemciyle, 10 bin elamanla bile bağlı listenin yavaş olduğu anlaşılıyor. Evet, bende her ikisi de yaklaşık 6 sn. sürdü ama dizide defalarca yaptığım denemelerde hep 6 sn. altında kalıyor; diğeri ise üstünde. Öyleyse Bjarne Stroustrup yerden göğe kadar haklı; öyle ya o bir üstad!

Kesin sonuçlar (100 bin için) ise şöyle:
'(ilk veri Vector List, ikincisi Linked List)'
Alıntı:

>

**
real 10m11.138s
user 10m9.142s**
: : :
real 12m38.674s
user 12m36.583s
Dip Not: Şu an İstanbul'da güneş doğuyor ve bütün bu tespitler sabah bereketi olmalı. Gece çalışmak bence o kadar verimli değil. Tabi biraz uyuyup uyanmak ve sizler gibi değerli insanlardan feyzlenmek işin tadını arttırıyor...:)

Teşekkürler...

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

February 24, 2012

Ekrana yazmayı dahil etmiyorsun, değil mi? Ben onu çıkarttıktan sonra her ikisi de 1.8 saniye sürdü. Fark görebilmek için 10 binden daha fazla elemanla denemek gerekiyor.

Bir de, düğümün gözüyle bakıldığında göstergenin ismi 'tail' olmamalı, 'next' olmalı. Çünkü düğüm sonraki düğümü gösterir. 'tail' diye de bir kavram vardır ama o bağlı listeye aittir, düğümlerine değil:

struct Node {
   int data;
   Node* next;
}

struct List {
   Node* head;
   Node* tail;
}

Düğümün içindekine 'tail' deyince ve liste ile bu kadar yakın bir kavram olunca kafa karıştırma tehlikesi var.

Ali

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