Jump to page: 1 2 3
Thread overview
Yığıt (sürüm2)
Sep 15, 2012
Salih Dinçer
Sep 15, 2012
Salih Dinçer
Sep 15, 2012
Salih Dinçer
Sep 27, 2012
Salih Dinçer
Sep 27, 2012
Salih Dinçer
Sep 27, 2012
Salih Dinçer
Sep 27, 2012
Salih Dinçer
Sep 27, 2012
Salih Dinçer
Sep 27, 2012
Salih Dinçer
Sep 29, 2012
Salih Dinçer
Sep 30, 2012
Salih Dinçer
Jan 04, 2013
Salih Dinçer
Dec 02, 2013
Salih Dinçer
Dec 02, 2013
Salih Dinçer
Dec 03, 2013
Salih Dinçer
Dec 05, 2013
Salih Dinçer
September 15, 2012

Merhaba,

Zafer'in başlattığı ve bir süre önce C++'daki olanağı görünce devam ettirdiğim basit bir yığıt yapısının son halini yayınlıyorum. Bilmiyorum, D'de aynı özelliklerde bir olanak var mı? Ama yoksa da koysalar ne iyi olurdu...:)

Çünkü birebir C++'daki ile aynı şekilde çalıştığı gibi (bunu çözdüğüm 5 örnekten ve referans verdiğim adreslerden anlayabilirsiniz) aralıklarla da çalışıyor. Üstelik ikinci bir bonus olarak 'clear()' üye işlevini ekledim. Böylece 5 üye işlev aralık olanağı ile birlikte 8 üye işleve çıktı. Bilmiyorum başka şeye ihtiyaç var mı?

struct Stack(T) {
   private int konum;
   private T[] stack;

   public:
   void push(T)(T veri) @property
   {
       stack ~= veri;
       konum++;
   }

   T pop() @property
   {
       return stack[--konum];
   }

   ref T top() @property
   {
       return stack[konum - 1];
   }

   /*** BONUS ***/

   void clear() @property
   {
       stack = stack.init;
       if(stack.length) {
           throw new Exception("Stack is not empty!");
       } else konum = 0;
   }

   void popFront() @property
   {
       --konum;
   }

   T front() const @property
   {
     return stack[konum - 1];
   }

   /*** BONUS ***/

   bool empty() const @property
   {
       return konum == 0;
   }

   int size() @property
   {
     return konum;
   }
}

import std.stdio;
void main() {
   Stack!int mystack;
   int sum;

   foreach(i; 0..11) mystack.push(i);

   while (!mystack.empty()) {
       sum += mystack.top();
       mystack.pop();
   }
   sum.writeln(" Sum of the numbers...");
   // example #1: http://www.cplusplus.com/reference/stl/stack/empty/


   foreach(i; 0..5) mystack.push(i);

   write("Popping out elements...");
   while (!mystack.empty()) {
     mystack.top().write(" ");
     mystack.pop();
   }
   writeln();
   /* example #2: http://www.cplusplus.com/reference/stl/stack/pop/
    * example #3: http://www.cplusplus.com/reference/stl/stack/push/
    */

   "0. size: ".writeln(mystack.size());
   foreach(i; 0..5) mystack.push(i);
   "1. size: ".writeln(mystack.size());
   mystack.pop();
   "2. size: ".writeln(mystack.size());
   // example #4: http://www.cplusplus.com/reference/stl/stack/size/

   mystack.clear(); // BONUS...:)

   mystack.push(10);
   mystack.push(20);
   mystack.top() -= 5 ;
   "mystack.top() is now ".writeln(mystack.top);
   // example #5: http://www.cplusplus.com/reference/stl/stack/top/

   foreach(range; mystack) range.writeln(); // BONUS...:)
   writeln("-THE END-");
}

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

September 15, 2012

İnsanoğlunun bir gözünü (dikkat iki gözünden bir tanesini!)
terazinin bir kefesine koymuşlar, diğer kesesine de dünyayı yine de göz ağır gelmiş... http://www.clker.com/cliparts/R/t/4/Q/u/c/eye-can-see-the-world-th.png

Hal böyleyken oldu mu sürüm 2.1...:)

Aslında aç gözlülük bir yana belki de boş boğazlılık. Hatta yaptığım boşuna bir kod yazmak/vakit harcamaktan öteye gidemez. Ancak en iyi test ortamının saha olduğu düşünülürse acaba bu yığıt yapısını sıralama algoritmaları dışında bir hesap makinesi gibi kullanırsak ne tür ihtiyaçlar doğlar:

  • İlk elemana erişme (Stack.first)
  • Son elemanın yedeğini alma (Stack.topBackup) '"Belki de ismi popBackup olmalıydı?"'

Evet, ben bunlara ihtiyaç duydum. Yaptığım ise basit bir Julian Date hesabıydı. Belki yedek almak çok şart değildi çünkü bunu o sırada bir yerel değişken ile yapabilirdik. Ancak yapı içindeki biraz daha işlevsel ve hatta tüm dizinin yedeğini alma gibi bir özellik ile daha işlevsel olabilir. Dedim ya göz ve terazi meselesi işte...:D

struct Stack(T) {
   private int konum;
   private T[] stack;
   T yedek;

   public:
   void push(T)(T veri) @property
   {
       stack ~= veri;
       konum++;
   }

   T pop() @property
   {
       return stack[--konum];
   }

   ref T top() @property
   {
       return stack[konum - 1];
   }

   /*** BONUS ***/

   ref T first() @property
   {
       return stack[0];
   }

   T topBackup(bool refresh = true) {
       if(refresh) yedek = pop;
       return yedek;
   }
   void clear() @property
   {
       stack = stack.init;
       if(stack.length) {
           throw new Exception("Stack is not empty!");
       } else konum = 0;
   }

   void popFront() @property
   {
       --konum;
   }

   T front() const @property
   {
     return stack[konum - 1];
   }

   /*** BONUS ***/

   bool empty() const @property
   {
       return konum == 0;
   }

   int size() @property
   {
     return konum;
   }
}

double julian(int year, int month, int day) {
	// convert Gregorian date to Julian day
	// Ref: Astronomical Algorithms by Jean Meeus
		if (month <= 2) {
			year -= 1;
			month += 12;
		}

		double a = floor(year / 100.0);
		double b = 2 - a + floor(a / 4.0);

		return floor(365.25 * (year + 4716)) +
		       floor(30.6001 * (month + 1)) + day + b - 1524.5;
	}

import std.math, std.stdio;
void main() {
 Stack!double julianDate;
 enum { day = 15, month = 9, year = 2012 };
 double sum = 0;

 //sum = julian(year, month, day); /*
 with(julianDate) { // Memory Calculator
   push(day); push(month);

   if(top <= 2) {
       top += 12;
       push(year - 1);
   } else push(year);

   push(2-floor(top/100.0) + floor(top/400.0));
   first += pop - 1524.5;
   top = floor(365.25 * (top + 4716));
   topBackup();
   top = floor(++top * 30.6001);
   push(topBackup(false));
   do sum +=pop; while(!empty);
 }//*/
 writefln("%.1f", sum);
}

Başarılar...

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

September 15, 2012

Alıntı (acehreli):

>
  • top'ın ayrıca şablon olmasının nedeni, topluluğun T'sinden başka türlerden elemanlar da ekleyebilmek, değil mi? Örneğin bir Stack!long'a bir int eklenebiliyor.

Açıkçası onu oraya kim koydu bilmiyorum, hiç dikkat etmemiştim ama faydalıysa dursun o zaman...:)

Alıntı (acehreli):

>
  • Acaba top'ın 'const' olanı da iyi olur mu? Böylece top, 'const Stack!long' ile uğraşılan bir durumda da çağrılabilir. Örneğin bir işlevin 'ref const Stack!long' aldığını düşün. O işlevin içinde top'ı çağırabiliyor musun?

Bence const olmamalı. Çünkü bu durumda işaret ettiği değişkenin içeriği değiştirilemez öyle değil mi?

Alıntı (acehreli):

>
  • BONUS açıklamalarından iki tane var. :) Yalnızca iki tanesi mi bonus, yoksa bütün o bölümler mi?

BONUS'ların sayısı arttığı için o bölgenin başını ve sonun ifade etmek istemiştim...

Alıntı (acehreli):

>
  • clear() konusunda aklıma bir şey geldi: Acaba çağıranlar üyelerin sonlandırıcılarının da işletilmelerini beklerler mi? Örneğin içinde 10 adet BenimYapım olan bir Stack!BenimYapım topluluğu olsa, clear() deyince 10 adet sonlandırıcı hemen işletilmeli mi? (Bunun yanıtını bilmiyorum.) Acaba bu Stack eski elemanların yerleri ancak tekrar kullanılırsa mı o sonlandırıcıları işletiyor? (Denemedim. :))

Buradaki temizleme işlemi çok işlevsel değil ama gerekirse class yaparak daha mı akıllıca yapılsa emin değilim. Ama o zaman, (zannedersem) top() üye işlevi bir değişken gibi çağrılamıyordu diye hatırlıyorum. Tabi sınıf olmanın with içinde bir avantajı daha var. İsimsiz olarak küme içinde çalışan bir nesne meydana getirilebiliyor. Sanırım diğer türlü önce dışarıda meydana getirmek gerekiyor ya da benim eksik bildiğim bir şeyler var...:D

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

September 15, 2012

Güzel. :)

  • top'ın ayrıca şablon olmasının nedeni, topluluğun T'sinden başka türlerden elemanlar da ekleyebilmek, değil mi? Örneğin bir Stack!long'a bir int eklenebiliyor.

  • Acaba top'ın 'const' olanı da iyi olur mu? Böylece top, 'const Stack!long' ile uğraşılan bir durumda da çağrılabilir. Örneğin bir işlevin 'ref const Stack!long' aldığını düşün. O işlevin içinde top'ı çağırabiliyor musun?

  • BONUS açıklamalarından iki tane var. :) Yalnızca iki tanesi mi bonus, yoksa bütün o bölümler mi?

  • clear() konusunda aklıma bir şey geldi: Acaba çağıranlar üyelerin sonlandırıcılarının da işletilmelerini beklerler mi? Örneğin içinde 10 adet BenimYapım olan bir Stack!BenimYapım topluluğu olsa, clear() deyince 10 adet sonlandırıcı hemen işletilmeli mi? (Bunun yanıtını bilmiyorum.) Acaba bu Stack eski elemanların yerleri ancak tekrar kullanılırsa mı o sonlandırıcıları işletiyor? (Denemedim. :))

Ali

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

September 15, 2012

Alıntı (Salih Dinçer):

>

Alıntı (acehreli):

>

bir işlevin 'ref const Stack!long' aldığını düşün. O işlevin içinde top'ı çağırabiliyor musun?

Bence const olmamalı. Çünkü bu durumda işaret ettiği değişkenin içeriği değiştirilemez öyle değil mi?

İşlevi yazan const almak istemiş çünkü bizim nesnemizi değiştirmeyeceği sözünü vermiş. Örneğin üsttekiniYazdır() gibi bir işlevin const olarak alması uygundur çünkü yazdıran bir işlevin yığıtta değişiklik yapması saçma olurdu.

Yalnızca bu kavrama odaklanan basit örnek:

import std.stdio;

struct Yığıt
{
   int eleman;

   ref int top()
   {
       return eleman;
   }
}

void üsttekiniYazdır(const ref Yığıt yığıt)
{
   writeln("Üstteki çok güzelmiş: ", yığıt.top());
}

void main()
{
   Yığıt yığıt;
   üsttekiniYazdır(yığıt);
}

O program derlenemez:

'Error: function deneme.Yığıt.top () is not callable using argument types () const'

C++'taki gibi olan çözümü, const olan ve olmayan iki top() tanımlamaktır:

   ref int top()
   {
       return eleman;
   }

   ref const(int) top() const
   {
       return eleman;
   }

Şimdi derlenir.

Aslında int gibi bir tür ise const olanın dönüş türü hiç ref de olmayabilir:

   int top() const
   {
       return eleman;
   }

Tabii eğer top() yoluyla erişim de sağlıyorsak, bu işi @property yoluyla da halledebiliriz:

import std.stdio;

struct Yığıt
{
   int eleman;

   // Değerini döndürür
   int top() const @property
   {
       return eleman;
   }

   // Elemana yeni değer atar; artık hiçbir şey döndürmüyor
   void top(int değer) @property
   {
       eleman = değer;
   }
}

void üsttekiniYazdır(const ref Yığıt yığıt)
{
   writeln("Üstteki çok güzelmiş: ", yığıt.top());
}

void main()
{
   Yığıt yığıt;
   yığıt.top = 42;            // <-- Bekleneceği gibi bu da çalışır
   üsttekiniYazdır(yığıt);
}

Ali

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

September 27, 2012

Bu iletiyi yeni görüyorum!

Herhalde tatile çıktığımdandır...:D

Bu durumda iki top() işlevi ile sürüm 2.2'ye geçebiliriz...:)

/*
 yığıt2.d (27.09.2012)
 sürüm: 2.2
 yazanlar: Ali Çehreli, Erdem Öncel, Salih Dinçer, Zafer Çelenk
*/
struct Stack(T) {
   private int konum;
   private T[] stack;
   T yedek;

   public:
   void push(T)(T veri) @property
   {
       stack ~= veri;
       konum++;
   }

   T pop() @property
   {
       return stack[--konum];
   }

   ref T top() const @property
   {
       return stack[konum - 1];
   }

   /*** BONUS ***/

   void top(T)(T value) @property
   {
       stack[konum - 1] = value;
   }

   ref T first() @property
   {
       return stack[0];
   }

   T topBackup(bool refresh = true) {
       if(refresh) yedek = pop;
       return yedek;
   }
   void clear() @property
   {
       stack = stack.init;
       if(stack.length) {
           throw new Exception("Stack is not empty!");
       } else konum = 0;
   }

   void popFront() @property
   {
       --konum;
   }

   T front() const @property
   {
     return stack[konum - 1];
   }

   /*** BONUS ***/

   bool empty() const @property
   {
       return konum == 0;
   }

   int size() @property
   {
     return konum;
   }
}

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

September 27, 2012

Opsss!

Aşağıdaki uygulamayı yurkarıdaki 2.2 sürümü ile denediğimde hatalar alıyorum!

double julian(int year, int month, int day) {
   // convert Gregorian date to Julian day
   // Ref: Astronomical Algorithms by Jean Meeus
       if (month <= 2) {
           year -= 1;
           month += 12;
       }

       double a = floor(year / 100.0);
       double b = 2 - a + floor(a / 4.0);

       return floor(365.25 * (year + 4716)) +
              floor(30.6001 * (month + 1)) + day + b - 1524.5;
}
import std.math, std.stdio;
void main() {
 Stack!double julianDate;
 enum { day = 15, month = 9, year = 2012 };
 double sum = 0;

 //sum = julian(year, month, day); /*
 with(julianDate) { // Memory Calculator
   push(day); push(month);

   if(top <= 2) {
       top += 12;
       push(year - 1);
   } else push(year);

   push(2-floor(top/100.0) + floor(top/400.0));
   first += pop - 1524.5;
   top = floor(365.25 * (top + 4716));
   topBackup();
   top = floor(++top * 30.6001);
   push(topBackup(false));
   do sum +=pop; while(!empty);
 }//*/
 assert (sum == julian(year, month, day));
 writefln("%.1f", sum);
}

Alıntı:

>

yığıt2.d(25): Error: cast(double)this.stack[cast(ulong)(this.konum - 1)] is not an lvalue
yığıt2.d(30): Error: template yığıt2.Stack!(double).Stack.top(T) conflicts with function yığıt2.Stack!(double).Stack.top at yığıt2.d(23)
yığıt2.d(90): Error: template instance yığıt2.Stack!(double) error instantiating

İlk hata dışında kalanları (conflicts & instantiating) halletmesi kolay gibi çünkü bunlar şablon hataları. İşlev şablonunu kaldırdığımda bu hatalar gidiyor; yapının işlevselliği de...:(

Tabi diğer hatayı halledemediğimi belirtmeliyim. Bunu halletsek bile şablon kullanmak, farklı veri türlerine göre yığıt oluşturabileceğimiz için iyi gözüküyor. Bu durumda sürüm 2.1'e geri dönüyoruz...:)

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

September 27, 2012

Teşekkürler, gördüğüm kadarıyla bütün bunları' top()' işlevinin her türlü kullanımı için yapıyoruz. Ayrıca bir benzeri olan 'first()' işlevine de uyarladığımızda işlev sayısı 2'den 6'ya çıkıyor. Çünkü son düzenlemede bir tane daha ekledik...:)

Tamam, belki derlenirken derleyici bu 3 işlevden birini seçiyor (bu arada her ikisi veya üçü kullanıldığında da object koda dahil oluyor mu? Sanırım oluyor ve bunu işlevleri farklı isimlendirerek (adreslere yerleştirerek) yapıyor!) ama git gide basitlikten uzaklaşıyoruz gibime geldi. Hatta espri yoluyla terazi, dünya ve göz misaliyle bir nevi kendimi eleştirdiğim sırada kendimi frenleyip ileriye gitmemeliydim. Bence tek işlevli (const olmadan) kullanım için yeterli ama tarihte downgrade olan ilk yazılım olmamak için 2.2 için şu düzenlemeye gidebiliriz:

class Stack(T) {
   private int konum;
   private T[] stack;
   T yedek;
   :    :    :
}

import std.math, std.stdio;

void main() {
 enum { day = 15, month = 9, year = 2012 }
 double sum = 0;

 with( new Stack!double ) {
   :    :    :
 }
}

Böylece 'with()' ile isimsiz nesne (anonymous object) oluşturabiliyoruz...

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

September 27, 2012

Opss!

Ali hocamın iki işlevini de dahil ettiğimde işler ciddi şekilde karıştı! Öncelikle matematiksel hesap yapan uygulama yanlış hesaplamaya başladı ki assertion failure hatası vermemesi için o satırı gizledim ve 27 Eylül 2012 için şu sonuç ile bir de hata aldım:

'75195263.5
core.exception.RangeError@yığıt2(32): Range violation
'
Normalde 2456185.5 değerini almalıydım. Demek ki top() işlevi istediğimiz gibi her satırda çalışmıyor. Sondaki hata ise üsttekiniYazdır() işlevini çağırdığım satır ki şu şekilde kullandım:

import std.math, std.stdio;

void üsttekiniYazdır(T)(const ref Stack!T yığıt)
{
 writeln("Üstteki çok güzelmiş: ", yığıt.top());
}
void main() {
 enum { day = 15, month = 9, year = 2012 }
 double sum = 0;

 auto yığıt = new Stack!double;
 with(yığıt) {
   :    :    :
 }
 //assert(sum == julian(year, month, day));
 writefln("%.1f", sum);
 üsttekiniYazdır(yığıt);

Alıntı (acehreli):

>

Alıntı (Salih Dinçer):

>

Bu durumda sürüm 2.1'e geri dönüyoruz...:)

Sürümlerin öncelikle testlerini geçmeleri gerekmez mi? ;)
Gerekirdi...:)

Bu arada son değişiklikler ile DMD 2.059 da derlemekte...

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

September 27, 2012

Cuma akşamı bereketine iki düzeltme daha!

Öncelikle kendi hatalarımı düzelteyim: :D :D :D

  • Biz bugünün tarihini değil kodu ilk yazdığım 15 Eylül 2012 tarihini hesaplatıyoruz,
  • Yanlış hesaplamasının sebebi herhalde yanlışlıkla with() içini değiştirmiş olmam olabilir ki bulamadım ama CTRL+Z ile çözdüm...

Var olan üçüncü bir hata var ki o da dizi elemanlarına erişirken kullandığım konum değişkeni! Meğer, işlem sonucunu ekrana yazdırırken konum değeri -1 oluyormuş. Bu da range violation hatasına sebebiyet veriyormuş. Bunu şu üç satır ile anladım:

 yığıt.push(0);
 yığıt.stack.writeln;
 üsttekiniYazdır(yığıt);

Çıktısı:
'[-1522.5, 306, 2.4574e+06, -13, 2.4574e+06, 0]
Üstteki çok güzelmiş: -1522.5'

Sanırım burada 4. bir hata daha var! O da konum değeri -1 ise run-time hatası vermeyip T.init göndermemesi. Belki throw new ile hata da attırabiliriz.

Ayrıca dizideki elemanlara erişimi sonsuza (GC temizleyene) kadar erişimi iptal etmek için stack.length'i konum'un değerine göre de düşürebiliriz. Gerçi bu sınıf bir kütüphane içine girdiğinde private özellikleri çalışacağından diziye yukarıdaki gibi erişemeyeceğiz.

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

« First   ‹ Prev
1 2 3