Dynamic nested loops in c#: Dinamik iç içe döngüler…

English version will be available soon!

for (int i = 0; i < 10; i++)
{
    Console.WriteLine(i);
}

Yukarıda gördüğünüz C# ile yazılmış basit bir döngü yapısı. 0 ile 9 arasıdaki (0 ve 9 dahil) rakamları ekrana yazdırıyor. Yani tek basamaklı doğal sayıları. Peki 2 basamaklı doğal sayıları nasıl ekrana yazdıracağız? Şöyle,

for (int i = 1; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
    {
        Console.WriteLine(i.ToString() + j.ToString());
    }
}

Peki 3 basamaklı doğal sayıları? (i değişkeninin 1’den başladığına dikkat edin lütfen)

for (int i = 1; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
    {
        for (int k = 0; k < 10; k++)
        {
            Console.WriteLine(i.ToString() + j.ToString() + k.ToString());
        }
    }
}

Dikkat ederseniz her defasında bir döngü (her basamak için) en içteki döngününniçerisine ekleniyor. Kısacası herbir basamak için bir döngü…N basamak için iç içe n döngü…Peki işi biraz daha karışık hale getirirsek?

Yukarıdaki örneklerimizde sayının basamakları birbiri ile aynı olabilir. Peki 3 basamaklı ve basamakları birbirlerinden farklı olan sayıları nasıl bulabiliriz?

for (int i = 1; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
    {
        for (int k = 0; k < 10; k++)
        {
            if (i != j && i != k && j != k)
                Console.WriteLine(i.ToString() + j.ToString() + k.ToString());
        }
    }
}

En içteki döngüye bir koşul ifadesi eklememiz yeterli oldu. Buraya kadar herşey kolay…Şimdi olayın zor olan kısmına gelelim. Eğer 1 ile N basamaklı (1, 2, 3, 4 ….. N basamaklı) sayıların tamamını elde etmek istersek ne yapacağız? Bu halde N adet iç içe döngü oluşturmamız gerekir (dinamik bir döngü)…Ancak bunu bir programlama dili ile, dinamik olarak yapmak mümkün değildir (en azından benim bildiklerim ile).

Böyle birşey ne işimize yarar peki? Çok işimize yarar…Oyunlarda kullanılabilir, istatistik ve olasılık hesaplarında kullanılabilir vs. vs.

Neyse, imdadımıza yine recursive (yineleyen) metotlar yetişiyor… Sonuca gelelim…

 
private void DynamicNestedLoop(int number, int index)
{
    // get the current digit indicated with index
    // sayıdan index ile belirtilmiş basamağı al
    int currentdigit = GetDigitAtIndex(number, index);
 
    // if the current digit is 9 then we have to reset the number
    // eğer şu anki basamak 9 ise sayıyı sıfırlamamız gerekiyor
    if (currentdigit < 9)
    {
        // get the new number. for instance if the current number 1000 
        // and index = 3 then new number will be 1001
        // yeni sayıyı al, örneğin şu anki sayımız 1000 ise
        // üretilecek yeni sayımız 1001 olacaktır
        int newnumber = ChangeDigitAtIndex(number, index, currentdigit + 1);
 
        Console.WriteLine(newnumber);
 
        // call the method again with the current index
        // metodu mevcut index ile yeniden çağır
        DynamicNestedLoop(newnumber, index);
    }
    else
    {
        // if the current index greater than 0 
        // (if we are not dealing with the first digit)
        // eğer şu anki indeximiz 0'dan büyükse
        // yeni sayının ilk basamağı ile uğraşmıyorsak
        if (index > 0)
        {
            // get the previous digit of the number
            // because we will increase it
            // sayının bir önceki basamağını al
            // önceki basamağı arttıracağız çünkü
            int prevdigit = GetDigitAtIndex(number, index - 1);
 
            // if the previous digit is less than 9
            // eğer bir önceki basamağımız 9'dan küçükse
            if (prevdigit < 9)
            {
                // increase the previous digit
                // bir önceki basamağı arttır
                int newnumber = ChangeDigitAtIndex(number, index - 1, prevdigit + 1);
 
                int numberlength = number.ToString().Length;
 
                // reset the number to its minimum value
                // set every digit to zero beginning from the previous index
                // sayıyı bir önceki basamaktan başlayarak sıfırla
                // diğer basamakları sıfırla
                for (int i = numberlength - 1; i > index - 1; i--)
                    newnumber = ChangeDigitAtIndex(newnumber, i, 0);
 
                Console.WriteLine(newnumber);
 
                // call method again from the beginning
                // metodu en başından yeniden çağır
                DynamicNestedLoop(newnumber, numberlength - 1);
            }
            else
            {
                // if previous digit is 9 than look for other digits
                // eğer bir önceki basamak 9 ise diğer basamakları kontol et
                DynamicNestedLoop(number, index - 1);
            }
        }
    }
}

Yukarıdaki kodu kullanarak dinamik iç içe döngüleri kullanarak elde edeceğiniz sonuçları, recursive metot kullanarak elde edebilirsiniz. Mesela 2 basamaklı tüm sayıları bulmak için metodu,

DynamicNestedLoop(100, 2);

3 basamaklılar için,

DynamicNestedLoop(1000, 3);

şeklinde çağırmanız yeterli olacaktır. Dikkat edin ilk parametre seçilen basamak sayısı kullanılarak oluşturulabilen en küçük sayı. İkinci parametre ise sayıyı bir string dizisi olarak düşünürseniz, bu dizinin son elemanına ait indexi. Bütün yorumları Türkçe ve İngilizce olarak ayrı ayrı yazdım. Yorumları dikkatlice okuyun lütfen…

Peki ya sayıları oluşturmak için kullanabileceğimiz rakamlar sınırlı olursa? Yani yalnızca 2,3,7,6,8,0 rakamlarını kullanarak N basamaklı sayıları (N rakam havuzunun boyutundan küçük olmak kaydıyla) nasıl bulabiliriz?

Bu sorunun yanıtı da bir sonraki yazımda…Umarım…

, , , , ,

4 Responses to Dynamic nested loops in c#: Dinamik iç içe döngüler…

  1. Ahmet BÜTÜN 23 Eylül 2011 at 9:39 PM #

    Askerlik dönüşü MasterMind oyununu yazarken hazırlamıştım bu yazıyı. Şimdi üzerinden tekrar bi geçip okudum da, kafam baya bi karışıkmış herhalde yazarken yazıyı. Kimi cümleler düşük ve anlaşılması zor olmuş 🙂 Düzeltemiyorum da 🙂

  2. Ahmet BÜTÜN 23 Eylül 2011 at 9:59 PM #

    Neyse biraz düzenledim.

  3. Zehra 22 Ekim 2011 at 3:19 PM #

    sımdı benım bı odevım var da bunlarla ılgılı bı turlu ısın ıcınden cıkamadım. takvım yapmamız gerekıyo. bı ıkı tane daha var ama bunu ogrenırsem belkı onları da yapabılırım.

    February 2009
    S M Tu W Th F S
    1 2 3 4 5 6 7
    8 9 10 11 12 13 14
    15 16 17 18 19 20 21
    22 23 24 25 26 27 28

    tabıkı alt alta denk gelıyo ama debug yaptıgımızda boyle bıseler cıkması gerek. 🙂

  4. Ahmet BÜTÜN 02 Kasım 2011 at 1:40 PM #

    Merhaba Zehra,

    Ödevinin bu konuyla ilgiil olduğunu sanmıyorum. Yani takvim yapmak ile dinamik iç içe döngüler…Bence basit döngülerler takvim olayını çözmen mümkün.

Bir cevap yazın

Font Resize