C# İle biLGİsayar programlama temelleri (C# Programlama Kitabı) Svetlin Nakov & Co



Yüklə 3,36 Mb.
səhifə22/31
tarix03.11.2017
ölçüsü3,36 Mb.
#28822
1   ...   18   19   20   21   22   23   24   25   ...   31

10.4 Doğrudan ve Dolaylı Özyineleme

Bir metot gövdesi içinden aynı metotun kendisine çağrı yapmışsa, bu doğrudan özyineleme veya direkt özyinelemedir.


Verilen bir A metotu herhangi bir B metotunu çağırıyor ve bu B metotu da verilen bir C başka metotunu çağırıyor ve bu C metotu da gerisin geriye tekrar A metotunu çağırmışsa, bunun adı literatürde dolaylı özyineleme veya A, B ve C metotları aralarında indirekt özyineleme vardır demeklerdir.
Dolaylı özyineleme çağrılarında birden fazla metot zinciri var olabilir, ancak koşullara veya verilere, parametre değerlerine bağlı olarak bir metot bir başka metota özyineleme çağrısı yaparken, yine başka nedenlerle bir başka metota özyineleme çağrısı yapabilir.


10.5 Özyinelemenin Sonlandırılması

Özyinelemeli programlamada dikkat edilmesi gereken en önemli programlama tekniği, özyineleme zincirlerinin son bulması gerektiği, yada somut sayıda tekrar ettikten sonra sonucu döndürmesidir. Bir başka deyişle, sonsuz sayıda özyineleme yoktur, bu durum yanlış programlamaya yol açar.


Bu nedenle özyinelemeyi sonlandırmak için bir yada daha fazla programlama yapısının metot içinde kullanılarak sonuç durumlarının programlanması programcının ana görevidir.

Yapılması gerekli bu eylem özyinelemenin sonlandırılması olarak da tanınır.


Fibonacci sayıları örneğinde, özyinelemenin sonlandırılma şartı n sayısının 2 veya daha az olmasıdır. Sonlandırılma şartının özyinelemeyi sonlandırmasından emin olmalıyız. Sonlandırılmaya gelen bir metot, daha fazla özyinelemeli çağrı yapmadan içinde bulunduğu çağrıyı sona erdirecek sonucu döndürmelidir. Kodda yapılan bir değerlendirme metotun özyinelemeli sonuç döndüren bir program mı, sonsuz döngü mü yapıldığını ortaya çıkaracaktır. Bu nedenle n=1 ve n=2 için sadece 1 döner.


10.6 Özyinelemeli Metot Oluşturulması

Özyinelemeli metotun her tekrarında elde edilen sonuç toplanarak gerçek sonuç oluşturulur. Her özyinelemeli çağrı sonunda problem daha küçük alt birimlere bölünür. Bu küçük problemlere ait alt çözümler bilgisayar tarafından saklanır ve dönüş sağlandığında birleştirilir. Birleştirme işlemi için özyinelemenin sonlandırılması gerekir.




10.7 Faktoriyelin Özyinelemeli Hesaplanması



Özyineleme kullanımını klasik bir örnek ile göstereceğiz – faktoriyelin özyinelemeli hesaplanması.
n faktöriyel (n! olarak gösterilir) 1 ve n (dahil) arasındaki her tamsayının çarpımlarından ibaret bir sayı olarak tanımlıdır. 0! = 1 kabul edilir.
n! = 1.2.3…n

10.7.1 Özyinelemeli Tanım



Faktoriyel hesaplanması için bir çözüm oluştururken faktoriyelin özyinelemeli tanımına başvurmak yerinde olacaktır:
n! = 1, n = 0 için

n! = n.(n-1)!, n > 0 için




10.7.2 Özyinelemeli Bağlılık Tespiti



Özyinelemeli bağlılık tespiti için uzun uğraş gerekebilir. Faktoriyel örneğimizde, problem analizi ve ilk birkaç durum için faktoriyel değerlerinin hesaplanması yeterlidir.

0! = 1

1! = 1 = 1.1 = 1.0!

2! = 2.1 = 2.1!

3! = 3.2.1 = 3.2!

4! = 4.3.2.1 = 4.3!

5! = 5.4.3.2.1 = 5.4!


Buradan kolayca tekrarlayan bağlılıkları görebilirsiniz:



n! = n.(n-1)!


10.7.3 Gerçekleştirilen Algoritma

Özyinelemenin sonlandırılma koşulu 1 değerine sahip n=0 şartıdır.


Diğer durumlarda n=n-1 için problemi çözmek zorundayız ve bu alt problem için dönen sonucun n ile çarpımını n=n-1 için döndürmeliyiz. Bu algoritma, belirli bir sayıdaki adım sonrasında özyinelemenin sonuna erişir ve 1…n arasındaki somut sayıdaki tamsayıların çarpımını hesaplar.
Bu önemli şartlar ile birlikte, faktoriyel hesaplayan metotu yazabiliriz:

static decimal Factorial(int n)

{

// The bottom of the recursion



if (n == 0)

{

return 1;



}

// Recursive call: the method calls itself

else

{

return n * Factorial(n - 1);



}

}

Bu metotu kullanarak konsoldan bir tamsayı okuyan, bu tamsayının faktoriyelini hesaplayan ve elde edilen değeri yazdıran bir uygulama geliştirebiliriz.

RecursiveFactorial.cs

using System;
class RecursiveFactorial

{

static void Main()



{

Console.Write("n = ");

int n = int.Parse(Console.ReadLine());
decimal factorial = Factorial(n);

Console.WriteLine("{0}! = {1}", n, factorial);

}
static decimal Factorial(int n)

{

// The bottom of the recursion



if (n == 0)

{

return 1;



}

// Recursive call: the method calls itself

else

{

return n * Factorial(n - 1);



}

}

}


n=5 için uygulamanın çalıştırılması sonucu aşağıda verilmiştir:




n = 5

5! = 120



10.8 Özyineleme veya Yineleme?

Özyineleme kavramı öğretilirken genellikle faktoriyel hesaplama örnek olarak seçilmiştir, ancak diğerleri gibi bu durumda da özyineleme en iyi seçim değildir.


Verilen bir problem için yinelenen (ardışık) bir çözüm her zaman açık olmayabilir. Sıklıkla eğer bir problemin özyinelemeli tanımı verilmişse, özyinelemeli çözüm sezgisel ve çok zor olmamalıdır.
Faktoriyel örnek için yinelemeli çözümün gerçekleştirilmesi özyineleme kadar kısa, basit ve hatta biraz daha verimli görünmektedir.

static decimal Factorial(int n)

{

decimal result = 1;


for (int i = 1; i <= n; i++)

{

result = result * i;



}
return result;

}

Bu bölümde daha sonra özyineleme ve yineleme kullanmanın avantaj ve dezavantajlarını dikkate alacağız.
Şu andan itibaren özyinelemenin gerçekleştirilmesi ile devam etmeden önce şunu da hatırlatmamız gerekir ki, yinelenen bir değişebilir şart üzerinde düşünmeli ve bu şart sonrasında daha iyi bir çözüm bulmalıyız.
Özyineleme kullanılarak çözülen bir probleme göz atalım. Bu örnek için yinelemeli bir çözümü de dikkate alacağız.


Yüklə 3,36 Mb.

Dostları ilə paylaş:
1   ...   18   19   20   21   22   23   24   25   ...   31




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©muhaz.org 2024
rəhbərliyinə müraciət

gir | qeydiyyatdan keç
    Ana səhifə


yükləyin