February 16, 2012

Kusura bakmayın ben yanlış anlamışım. Aslına bakarsanız burada yapılmak istenen tam olarak nedir henüz anlayabilmiş değilim. Sanırım 3 kişi anlayabildiğine göre bende bir sorun var...:)

Biri bana 3 yaşındaki çocuğun anlayabileceği şekilde anlatabilir mi? Çünkü olaylara farklı açılardan baktığım için görünürdeki dikkatimi dağıtabiliyor. Hoş, bu vesileyle 'random.d''ye girdim ve "benzersiz" ile "her seferinde benzersiz" kavramlarını sayenizde irdeledim...

Bu arada ancak Erdem'in çözümünde eleman sayısı istenen sayıya eşit veya büyük olmaması gerekiyor. Eğer eşit olursa sıralama değişmezken büyük olduğu için doğal olarak çalışma zamanı hatası alıyoruz. Lütfen 'Erdem Test'i açınız. Ayrıca en benzersiz değerleri döndüren 'unpredictableSeed()' olduğunu gördüm. Ali hocam konuyu daha iyi irdeleyecektir. Denemek isteyenler için aşağıya kodu alıntılıyorum:

/*
rasgele.d (16.02.2012)
*/
import std.stdio, std.random;

int[] rasgeleDizi(int adet, bool benzersiz_ise) {
   int[] dizi;
   int[] rakamlar = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 99];

   if(benzersiz_ise)
   {
       foreach(i; randomSample(rakamlar, adet)) dizi ~= i;
   }
   else
   {
       for(int i = 0; i < adet; i++) dizi ~= uniform(0, 10);
   }

   return dizi;
}

void main() {
   int i = 0;
   int[] z = rasgeleDizi(10, false);             // Zafer'in çözümü
   int[] e = rasgeleDizi(10, true);              // Erdem'in çözümü
   int[] d = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];   // Digital Mars'ın çözümü
   auto rnd = Random(unpredictableSeed);
/* @property uint unpredictableSeed();
       A "good" seed for initializing random number engines.
       Initializing with unpredictableSeed makes engines
       generate different random number sequences every run.
*/
   //writeln (rasgeleDizi(100, true));/*       Erdem Test

   foreach(r; randomCover(d, rnd))
   {
       writefln("%s\t%s\t%s", z[i], e[i], r);
       i++;
   }//*/
}

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

February 16, 2012

Sanırım şimdi anladım...:)

Çıkartma işlemi sanki daha kolay o yüzden ikinci bölümünü sonraya bırakalım, olur mu? Şu kodu denedim ve belki başlangıç için temel olabilir ama çalışmadığını belirtmeliyim. Ayrıca son sürümde 'insert()' yerine, emekliye ayrıldığı için sadece 'insertInPlace()' çalışacakmış, bilginize...

   auto i = uniform(0, 9);
   int[] dizi = [i];
   for(int a = 0; a < 10; a++) {
       writeln(i, dizi);
       i = uniform(0, 9);
       if (dizi.back > i) dizi.insert(dizi.length-1, i);
       else dizi.insert(dizi.length, i);
   }

Çıktısı ise aşağıdaki gibi ama sonraki satırlardan anlayacağınız üzere, sadece son elemana baktığı için istediğimiz olmuyor. Biraz daha düşünmemiz gerekiyor...:)

'7[7]
0[0, 7]
1[0, 1, 7]
8[0, 1, 7, 8]
8[0, 1, 7, 8, 8]
8[0, 1, 7, 8, 8, 8]
7[0, 1, 7, 8, 8, 7, 8]
6[0, 1, 7, 8, 8, 7, 6, 8]
4[0, 1, 7, 8, 8, 7, 6, 4, 8]
1[0, 1, 7, 8, 8, 7, 6, 4, 1, 8]'

Başarılar...

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

February 16, 2012

Hayır, bunu diğer konuyla ilgili olarak başlatmamıştım. Bu soru Stroustrup'un o sunumunda var. Oradan aktardım.

Tamam, sort() yöntemi iyi ama sıralama algoritmaları normalde O(N log(N)) karmaşıklıkta işlerler. Burada ise elimizde zaten her zaman için sıralı bir dizi olacak. O yüzden sort()'u çağırmak yerine şu daha hızlı olabilir: elemanın dizide nerede bulunması gerektiğini bulalım ve o araya yerleştirelim. Bu daha hızlı olacaktır çünkü yerin bulunması için ikili arama kullanılırsa log(N) karşılaştırma yeter. (İkili arama yerine sıralı arama da olabilir. O zaman da elemanın yeri ortalama N/2 karşılaştırmada bulunur.)

Karmaşıklık kavramına yabancı olan arkadaşlar için: Bu hesaplardaki log'lar hep 2 tabanındadır. Örneğin 1000 eleman varsa log(1000) 9 ile 10 arasında bir sayı olduğundan en fazla 10 karşılaştırmada yerimizi buluruz. 9 ile 10 arasında olması da şöyle bulunuyor: 2 üzeri 9 512'dir ve 2 üzeri 10 1024'tür. 1000 değeri bu iki değer arasında olduğuna göre log(1000) 9 ile 10 arasında bir sayıdır.

Programlarınızı değiştirmek istemiyorum tabii ama sort()'tan daha hızlı bir yöntem olduğunu hatırlatmak istedim. (Gerçi sort() da belki benim düşündüğümden akıllıdır ve zaten neredeyse sıralı olduğunu keşfeder. Konuyu daha da dağıtırsam, aslında sort()'a da hangi algoritmayı kullanacağı söylenebiliyor galiba.)

Ali

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

February 16, 2012

Alıntı (erdem):

>

İlk verilen

> int[] sayilar = [5, 1, 4, 2];
> ```

> dizisi sırasız değil mi.

Konuyu tam anlatamadım. :) Evet, sayılar belirsiz sırada geliyorlar ama dizi olarak değil, tek tek geliyorlar. Bizim amacımız onları her zaman için sıralı olarak bir dizide tutmak. Yani 5, 1, 4, 2 sayıları geldikçe (bir döngüde rasgele oluşturabiliriz) dizi şu aşamalardan geçecek:

'[ ]            5 ekle:
[ 5 ]          1 ekle:
[ 1, 5 ]       4 ekle:
[ 1, 4, 5 ]    2 ekle:
[ 1, 2, 4, 5 ]'

Birinci adımda öyle sıralı bir dizi elde ettikten sonra ikinci aşamaya geçiliyor. Rasgele indeks değerleri gelecek ve biz o indeksteki elemandan kurtulacağız. Sırayla 1, 2, 0, 0 geldiğinde dizi şu aşamalardan geçecek (indeksler dizinin hep o andaki durumuna göre; yoksa tek elemanlı dizide 2 indeksi kullanılamazdı):

'[ 1, 2, 4, 5 ] 1 indeksliyi çıkart:
[ 1, 4, 5 ]    2 indeksliyi çıkart:
[ 1, 4 ]       0 indeksliyi çıkart:
[ 4 ]          0 indeksliyi çıkart:
[ ]'

**Ek:** Sayılar tekrarlı olabilir. Elimizde sıralı bir dizi var, hangi sayı geldiyse onu diziye ekleyeceğiz ve elimizde yine sıralı bir dizi olacak.

Ali

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

Alıntı (Salih Dinçer):

>

sadece son elemana baktığı için

İkili arama gibi hızlı bir algoritmayı bir kenara bırakalım ve sıralı arayalım. En baştan başlayarak sayıdan daha küçük olanları geçelim ve sayıyı o noktaya ekleyelim. (Stroustrup bu denemede kendisinin de öyle yaptığını söylüyor.)

Ali

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

February 17, 2012

O zaman şöyle bir şeyler olabilir mi acaba.

import std.stdio;
import std.random;

void main()
{
   int[] dizi;
   int rastgele;

   for (int i = 0; i < 5; ++i) {
       rastgele = uniform (0, 10);
       writeln("sayi ", rastgele);
       dizi = diziyeEkle(dizi, rastgele);
       writeln(dizi);
   }
}

int[] diziyeEkle(int[] dizi, int sayi)
{
   if (dizi.length == 0) {
           dizi ~= sayi;
           return dizi;
   }

   for (int i = 0; i < dizi.length; ++i) {
       if (sayi <= dizi[i]) {
           dizi = dizi[0 .. i] ~ sayi ~ dizi[i .. $];
           break;
       }

       if (sayi > dizi[i]) {
           dizi ~= sayi;
           break;
       }
   }
   return dizi;
}

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

February 17, 2012

Alıntı (Ali Çehreli):

>

Alıntı (Salih Dinçer):

>

sadece son elemana baktığı için
İkili arama gibi hızlı bir algoritmayı bir kenara bırakalım ve sıralı arayalım. En baştan başlayarak sayıdan daha küçük olanları geçelim ve sayıyı o noktaya ekleyelim. (Stroustrup bu denemede kendisinin de öyle yaptığını söylüyor.)
Anlıyorum...

Hocam şunu demek istiyor olmalısın:

/*
liste.d (17.02.2012)
*/
import std.array, std.stdio, std.random;

void main () {
   int[] dizi;// = [uniform(0, 9)];
   int[] rakamlar = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];
   auto rakam = Random(unpredictableSeed);
   uint dizin;

   foreach(r; randomCover(rakamlar, rakam)) {
       for(dizin = 0; dizin < dizi.length; dizin++)//çift satır!
           //if(dizi[dizin] < r) break; /* Ters [9..0]
           if(dizi[dizin] > r) break; //*/
       dizi.insertInPlace(dizin, r);
       writeln(r, dizi);
   }
}

'8[8]
2[2, 8]
9[2, 8, 9]
6[2, 6, 8, 9]
7[2, 6, 7, 8, 9]
5[2, 5, 6, 7, 8, 9]
4[2, 4, 5, 6, 7, 8, 9]
1[1, 2, 4, 5, 6, 7, 8, 9]
3[1, 2, 3, 4, 5, 6, 7, 8, 9]
0[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]'

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

February 17, 2012

Alıntı (acehreli):

>

En baştan başlayarak sayıdan daha küçük olanları geçelim ve sayıyı o noktaya ekleyelim. (Stroustrup bu denemede kendisinin de öyle yaptığını söylüyor.)

Stroustrup yaptığına göre bizde yapabiliriz deyip bende çözümü düşünmeye başladım ve tam birşeyler geliştirmiş ve sayfaya ekleyecekken Erdem'in mesajını gördüm :).

Zaten benim düşündüğümü kodlamıştı eline sağlık güzel olmuş dolayısıyla onun yazdığı kod üzerinden devam etmek daha güzel olur diye düşünüyorum. Ancak benim hazırladığım for döngüsünde çözümü biraz daha farklı kodlamıştım onu eklemek isterim.

..

   for (int i = 0; i < dizi.length; ++i)
   {
       if (deger < dizi[i])
       {
           siraliDizi = (dizi[0 .. i] ~ deger ~ dizi[i .. $]);
           return siraliDizi;
       }

       siraliDizi ~= dizi[i];
   }

..

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

February 17, 2012

Alıntı (Salih Dinçer):

>

Alıntı (Ali Çehreli):

>

İkili arama gibi hızlı bir algoritmayı bir kenara bırakalım ve sıralı arayalım. En baştan başlayarak sayıdan daha küçük olanları geçelim ve sayıyı o noktaya ekleyelim. (Stroustrup bu denemede kendisinin de öyle yaptığını söylüyor.)
Hocam şunu demek istiyor olmalısın:

Ama elimizde rakamlar gibi bir dizi yok. Sadece boş bir dizi var ve biz bu diziye sayıları ekleyeceğiz. Ayrıca aynı sayı birden fazla gelebiliyor.

Alıntı:

>

Evet, sayılar belirsiz sırada geliyorlar ama dizi olarak değil, tek tek geliyorlar. Bizim amacımız onları her zaman için sıralı olarak bir dizide tutmak. Yani 5, 1, 4, 2 sayıları geldikçe (bir döngüde rasgele oluşturabiliriz) dizi şu aşamalardan geçecek:

'[ ] 5 ekle:
[ 5 ] 1 ekle:
[ 1, 5 ] 4 ekle:
[ 1, 4, 5 ] 2 ekle:
[ 1, 2, 4, 5 ] 5 ekle: <-- bir kere daha 5 gelmiş olsaydı
[ 1, 2, 4, 5, 5 ]
'

Örneğin bir kere daha 5 gelseydi sonuç yukarıdaki gibi olacaktı.
Alıntı:

>

Stroustrup yaptığına göre bizde yapabiliriz deyip bende çözümü düşünmeye başladım ve tam birşeyler geliştirmiş ve sayfaya ekleyecekken Erdem'in mesajını gördüm :)

Ancak benim yazdığımda bir hata var ;-) Bir kaç kere denerseniz göreceksiniz.

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

February 17, 2012

Alıntı (erdem):

>

Ama elimizde rakamlar gibi bir dizi yok. Sadece boş bir dizi var ve biz bu diziye sayıları ekleyeceğiz. Ayrıca aynı sayı birden fazla gelebiliyor. Evet, sayılar belirsiz sırada geliyorlar ama dizi olarak değil, tek tek geliyorlar. Bizim amacımız onları her zaman için sıralı olarak bir dizide tutmak.
Sorun değil 'foreach()''in üstüne hemen şu satırı kullanabilirsin:

for(dizin = 10; dizin <= 9999; dizin++) rakamlar ~= uniform(0, 100);

Bu arada yazdığım kodda iki dizi (array) var. Bir tanesi boş olan ve zaten istediğimizi onun üzerinde yapıyor. Rakamlar ismindeki dizi ise dilediğimizde elle sayı ekleyebilmemiz içinde yani şu şekilde de kullanabilirdik:

int[] rakamlar = [ 5, 1, 4, 2 ];

Neyse, zaten bu sıralı arama algoritmasının yavaş olacağı aşikar. Örneğin 0'dan 99'a olan rasgele (tekrarlı) 10 bin sayı içeren bir diziyi sıralı tutmaya çalışmak Intel Atom N450 işlemci ile yaklaşık 7 saniye alıyormuş:

'salih@DB-N150-N210-N220:~/d.ders$ time ./liste

real 0m6.942s
user 0m6.852s
sys 0m0.012s'

Herhalde geliştirilmiş sıralama algoritmalarının en kötüsü bile daha iyi sonuç verecektir...:)

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