Thread overview
Dizilerin küçülme özelliği kullanarak yazılan bir palindrom programı
Apr 09, 2011
erdem
Apr 09, 2011
mert
Apr 10, 2011
erdem
April 09, 2011

Bu dizilerin küçülme özelliği çok hoşuma gitti. Ayrıca örneğin bir diziyi küçültmek istediğimizde geçen süre dizinin uzunluğundan bağımsızmış. İşte palindrom programı:

import std.conv, std.stdio;

int main (string[] parametreler) {

   // Program isminden kurtuluyoruz
   parametreler = parametreler[1 .. $];

   while (parametreler.length >= 2) {
       if (to!int(parametreler[0]) != to!int(parametreler[$ - 1])) {
           writeln ("palindrom değil");
           return 1;
       }
       parametreler = parametreler[1 .. $ - 1];  // her seferinde dizinin
                                                 // başından ve sonundan 1
                                                 // eleman kısaltıyoruz
   }

   writeln("palindrom");
   return 0;
}

Bu program kendisine parametre olarak geçilen sayıların palindrom olup olmadığını buluyor. Örneğin [1, 3, 6, 18, 6, 3, 1] palindrom iken [1, 3, 6, 18, 6, 3, 2] palindrom değil. Yani ilk elemanla son eleman eşit, ikinci elemanla sondan bir önceki eleman eşit vs.. bu şekilde giden sayılar palindrom oluyor. Programı şu şekilde kullanıyoruz:

'palindrom 34 95 48'

Bu şekilde kullandığımızda parametreler ["palindrom" "34" "95" "48"] değerlerini alıyor. İlk yaptığımız program ismini parametreler listesinden çıkarmak.

'!toint('dizgi')' ifadesi de dizgiyi tamsayıya çeviriyor. Hoş nedense bende bunu kullanmadan da çalıştı :)

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

April 09, 2011

Denedikten on dakika sonra kullanmayı başarabildim. klasör yoluna ~ ile girilince iki kez başlangıç dizini yaratıyordu. Bu örnek bana iki şeyi birden öğretti. Teşekkürler Erdem.

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

April 09, 2011

Evet, dilimler çok güçlü. :)

Aralıklar bölümünde başından daraltma konusunu şöyle yazıyorum:

Alıntı:

>

Aralığı daraltarak ilerlemek

Şimdiye kadar çoğu örnekte kullandığımız ilerleme yönteminde aralığın kendi durumunda değişiklik olmaz. Örneğin bir dizi elemanlarında indeks değerleri ile ilerlendiğinde dizi değişmez:

>     int[] dizi = [ 10, 11, 12 ];
>
>     for (int i = 0; i != dizi.length; ++i) {
>         write(' ', dizi[i]);
>     }
>
>     assert(dizi.length == 3);    // ← uzunluğu değişmez
> ```

>
> Farklı bir bakış açısı getiren diğer bir yöntem, aralığı başından daraltarak ilerlemektir. Bu yöntemde hep aralığın ilk elemanına erişilir ve aralık tükenene kadar başından daraltılır:
>
>
>
for ( ; dizi.length; dizi = dizi[1..$]) {
    write(' ', dizi[0]);     // ← hep ilk elemana erişilir
}
>

Yukarıdaki döngünün ilerlemesi, dizi'nin ilk elemanının dizi = dizi[1..$] ifadesi yoluyla dizi dışında bırakılması ile sağlanmaktadır. Dizi, o ifadenin etkisiyle aşağıdaki aşamalardan geçerek daralır ve sonunda tükenir:

'
[ 10, 11, 12 ]
[ 11, 12 ]
[ 12 ]
[ ]
'

İşte Phobos aralıklarındaki ilerleme kavramı, aralığı bu şekilde başından daraltma düşüncesi üzerine kuruludur. (BidirectionalRange aralıkları son taraftan da daralırlar.)

O örneği yalnızca bu tür ilerleme kavramını göstermek için verdim; normalde kendi kodlarımızda öyle döngüler yazmak zorunda kalmayız.

İkinci yöntemin bariz bir sakıncası, ilerlerken bir yandan da dizinin elemanlarının kaybedilmeleridir. Salt ilerlemiş olmak için elemanların diziden bu şekilde çıkartılmaları çoğu durumda istenmeyeceğinden; asıl topluluğun kendisi değil, yalnızca ilerlemek için oluşturulan başka bir aralık değiştirilir.

Aynı örnekte asıl dizinin uzunluğunun değişmemesi için örneğin bir dilimden yararlanılabilir. Bu sefer aralığın kendisi değil, onun elemanlarına erişim sağlayan bir dilim değiştiriliyor:

>     int[] dizi = [ 10, 11, 12 ];
>     int[] dilim = dizi;
>
>     for ( ; dilim.length; dilim = dilim[1..$]) {
>         write(' ', dilim[0]);
>     }
>
>     assert(dilim.length == 0);   // ← dilim boşalır
>     assert(dizi.length == 3);    // ← dizi değişmez
> ```

>
> Phobos algoritmaları da asıl topluluklar değişmesinler diye özel aralık türlerinden yararlanırlar.
>

Dilimden eleman çıkartmanın hızlı olmasının nedeni de yukarıda [ 10, 11, 12 ] diliminin başından eksilmesinde görülüyor: hiçbir şey yapmaya gerek yok; dizinin elemanlarını gösteren .ptr üyesi bir ilerletiliyor.

Bu arada, aralıklar çok kolay bir kavram, ama o bölümü yazarken anlatılacak çok şey olduğunu farkediyorum. Henüz akıcı olarak anlatmayı başaramadım.

Ali

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

Alıntı (acehreli):

>

Evet, dilimler çok güçlü. :)

Aralıklar bölümünde başından daraltma konusunu şöyle yazıyorum:

Bakalım aralıklar konusuna ne zaman geleceğim. Bu hızla gidersem 1-2 seneyi bulabilir :)

Bu arada dizilerin genişlemesi '~=' ile ve bellek ayırma şekli daha da ilginç. Ama o konuyu da daha sonraki bir mesaja bırakıyorum ;-)

Alıntı (acehreli):

>

Alıntı:

>
> >     int[] dizi = [ 10, 11, 12 ];
> >     int[] dilim = dizi;
> > ```

> >
> >
>

Ben bu dilimi boş dizi gibi düşünüyorum. Aslında 'dizi[]' ifadesi 'dizi[0 .. $]' a eşit galiba ama böyle düşünmek bana daha anlaşılır geliyor.

int[] dizi = [ 10, 11, 12 ];
int[] dilim; // boş bir dizi int[] dilim = null'un
// aynısı
assert(dilim is null);
dilim = dizi; // hala dizi içeriği kopyalanmadı sadece
// aynı yeri göstermeye başladılar
assert(dilim is dizi); // dilim ve dizi aynı sınırlara mı sahip
assert(dilim == dizi); // evet eşit :)



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

Alıntı (erdem):

>

Bakalım aralıklar konusuna ne zaman geleceğim. Bu hızla gidersem 1-2 seneyi bulabilir :)

Aralıklar gerçekten çok basit bir kavram. En temelde belirli üye işlevlere sahip olmak ilkesi üzerine kurulu. Örneğin 'empty', 'front', ve 'popFront()' üye işlevleri olan tür bir 'InputRange' aralığıdır.

Tabii o işlevlerin belirli biçimlerde işlemeleri de şart:

  • empty: aralık boş olduğunda true, değilse false

  • front: baştaki eleman

  • popFront(): baştakini aralıktan çıkart (başından daralt)

O kadarı, 'InputRange''lerle işleyen algoritmalarla kullanmak için yeterlidir. Temelde bu kadar basit. Diğer aralıklar ek işlevler gerektirirler:

  • InputRange olmak için yukarıdaki üç işlev

  • ForwardRange olmak için ayrıca save() işlevi

  • BidirectionalRange olmak için ayrıca back ve popBack() işlevleri

  • RandomAccessRange olmak için ayrıca [] işleci (aslında bu aralığın başka tanımları da var)

(Bunları iz bıraksın diye tekrarlıyorum; aslında kendim için! :D)

Ali

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