Ne özyineleme nedir ve bunu ne zaman kullanmalıyım?

oy
121

posta listeleri ve çevrimiçi tartışmalara düzenli gelip görünüyor konulardan biri Bilgisayar Bilimleri derecesi yapmanın yararları (veya bunların eksikliği) 'dir. Negatif parti için tekrar tekrar gelip görünüyor bir tartışma yıllardır bazı numarası için kodlama edilmiş ve onlar özyinelemeye hiç kullanılmamış olmasıdır.

Yani soru şu:

  1. özyineleme nedir?
  2. Ne zaman Özyinelemeyi kullanırsınız?
  3. Neden insanlar Özyinelemeyi kullanmıyorsun?
Oluştur 06/08/2008 saat 03:29
kaynak kullanıcı
Diğer dillerde...                            


40 cevaplar

oy
86

Iyi birkaç açıklaması vardır özyineleme bu thread, bu cevap size çoğu dilde kullanmak gerekir neden hakkındadır. * Majör zorunlu dil uygulamalarının çoğunda (C, C ++, Basic, Python yani her büyük uygulama Ruby, Java ve C #) yineleme özyineleme kat kat tercih edilir.

Yukarıdaki diller bir işlev çağırmak için kullandıkları adımlarımızı, nedenini görmek için:

  1. uzay üzerine oyulmuş olan yığın işlevin argümanları ve yerel değişkenler için
  2. işlevin argümanları bu yeni uzaya kopyalanır
  3. Kontrol işlevine atlar
  4. işlevin kod çalışır
  5. İşlevin sonuç bir dönüş değeri kopyalanır
  6. Yığın önceki konumuna geri sarılır
  7. kontrol işlevi çağrıldı yere geri atlar

Tüm bu adımları yapmak bir döngü içinde yineleme için gereken daha genellikle biraz daha zaman alır. Ancak, asıl sorun 1. adımda olduğunu. Çok program başladığında, onların yığın için bellek tek bir yığın tahsis ve onlar o bellek bittiğinde (genellikle her zaman olmasa nedeniyle özyinelemeye), program nedeniyle çöküyor yığın taşması .

Yani bu dillerde de tekrarlama yavaştır ve kilitlenme karşı savunmasız hale getirir. olsa kullanmak için bazı argümanlar hala vardır. Okumak için nasıl öğrendikten sonra Genelde, yinelemeli yazılı kod, daha kısa ve biraz daha zarif.

Dil uygulayıcılar denilen kullanabilirsiniz Orada bir teknik kuyruk çağrı optimizasyonu yığın taşması bazı sınıfları ortadan kaldırabilir. Özetleyecek olursak: Bir işlevin dönüş ifadesi sadece bir işlev çağrısının sonucu ise, o zaman yığının üzerine yeni bir düzey eklemek gerekmez, sen çağrılan işlev için mevcut olanı yeniden kullanabilirsiniz. Ne yazık ki, birkaç şart dil-uygulamaları kuyruk çağrı optimizasyonu inşa var.

* Ben Özyinelemeyi seviyorum. Benim favori statik dil hiç döngüler kullanmaz, tekrarlama defalarca bir şeyler yapmak için tek yoldur. Sadece özyineleme bunun için ayarlanmış değil dilde iyi bir fikir genellikle olduğunu düşünmüyorum.

** Bu arada Mario, senin ArrangeString fonksiyonu için tipik adı "katılmak" olduğunu ve seçtiğiniz dil zaten bir uygulaması olmaması halinde çok şaşırırım.

Cevap 06/08/2008 saat 06:09
kaynak kullanıcı

oy
63

özyineleme Basit ingilizce örneği.

A child couldn't sleep, so her mother told her a story about a little frog,
    who couldn't sleep, so the frog's mother told her a story about a little bear,
         who couldn't sleep, so the bear's mother told her a story about a little weasel... 
            who fell asleep.
         ...and the little bear fell asleep;
    ...and the little frog fell asleep;
...and the child fell asleep.
Cevap 04/05/2010 saat 17:38
kaynak kullanıcı

oy
49

En temel bilgisayar bilimleri anlamda, tekrarlama kendisini çağıran bir işlevdir. Bağlı bir liste yapıya sahip ki:

struct Node {
    Node* next;
};

Ve bağlantılı bir liste, özyineleme ile yapabilirsiniz ne kadar süre öğrenmek istiyorum:

int length(const Node* list) {
    if (!list->next) {
        return 1;
    } else {
        return 1 + length(list->next);
    }
}

(Bu, tabii ki hem döngü için yapılabilir, ancak kavramının bir örneği olarak yararlıdır olabilir)

Cevap 04/05/2010 saat 12:25
kaynak kullanıcı

oy
46

Bir fonksiyon bir döngü yaratarak kendisini aradığında, o tekrarlama bu. bir şey olduğu gibi iyi kullanır ve yineleme için kötü kullanımları vardır.

En basit örnek fonksiyonunun en son çizgi kendisine bir çağrıdır kuyruk özyineleme geçerli:

int FloorByTen(int num)
{
    if (num % 10 == 0)
        return num;
    else
        return FloorByTen(num-1);
}

kolayca daha verimli yineleme ile değiştirilebilir Ancak, bu bir topal, neredeyse anlamsız bir örnektir. Sonuçta, yineleme yukarıdaki örnekte fonksiyonu kendi içinde işlem ile karşılaştırıldığında önemli olabilir işlev çağrısı yükü, muzdariptir.

Bütün nedeni Özyinelemeyi yapmak yüzden daha ziyade yineleme daha yararlanmak olmalıdır çağrı yığını bazı akıllı şeyler yapmak için. Aynı döngü içinde farklı parametrelerle bir fonksiyonu birden çok kez ararsanız Örneğin, daha sonra bunu başarmak için bir yol dallanma . Klasik bir örnek Sierpinski üçgeni .

Burada görüntü açıklama girin

Çok basitçe özyineleme ile onlardan biri çizebilirsiniz burada 3 yönde çağrı yığını dalları:

private void BuildVertices(double x, double y, double len)
{
    if (len > 0.002)
    {
        mesh.Positions.Add(new Point3D(x, y + len, -len));
        mesh.Positions.Add(new Point3D(x - len, y - len, -len));
        mesh.Positions.Add(new Point3D(x + len, y - len, -len));
        len *= 0.5;
        BuildVertices(x, y + len, len);
        BuildVertices(x - len, y - len, len);
        BuildVertices(x + len, y - len, len);
    }
}

Eğer yineleme ile aynı şeyi yapmak çalışırsanız ben bunu başarmak için çok daha fazla kod alır bulacağınızı düşünüyoruz.

Diğer ortak kullanım durumları vb kateden hiyerarşileri, örneğin web tarayıcılarının, dizin karşılaştırmaları da yer alabilir

Sonuç

Pratik açıdan bakıldığında, tekrarlama size yinelemeli dallanma ihtiyacınız olduğunda en mantıklı.

Cevap 04/05/2010 saat 14:33
kaynak kullanıcı

oy
28

Özyineleme bölmek ve fethetmek zihniyet dayalı sorunların çözümünde bir yöntemdir. Temel fikir orijinal sorunu alıp kendisinin daha küçük (daha kolay çözülür) örneklerini bölmek, bu küçük örneklerini çözmek (genellikle tekrar aynı algoritmayı kullanarak) ve daha sonra nihai çözüm bunları yeniden birleştirmek olmasıdır.

klasik örneği n faktöriyel oluşturmak için bir rutindir. n Faktöriyel 1 ve n arasında tüm numaraları çarpılarak hesaplanır. C # tekrarlayıcı bir çözüm gibi görünür:

public int Fact(int n)
{
  int fact = 1;

  for( int i = 2; i <= n; i++)
  {
    fact = fact * i;
  }

  return fact;
}

Orada iteratif çözümü hakkında şaşırtıcı bir şey yok ve C # aşina kimseye anlamlı olmalıdır.

yinelemeli çözelti n'inci Faktöriyel n * Gerçek olduğunu tanıyarak bulunmuştur (n-1). Belirli bir Faktoriyel numara bir sonrakini hesaplayabilirsiniz ne olduğunu biliyorum Veya, Diğer bir deyişle için. İşte C # özyinelemeli çözümdür:

public int FactRec(int n)
{
  if( n < 2 )
  {
    return 1;
  }

  return n * FactRec( n - 1 );
}

Bu işlevin ilk kısmı olarak bilinen Baz Kılıf (ya da bazen Muhafız Madde) ve sonsuza çalışmasını algoritma engeller şeydir. Bu sadece işlev 1 ya da daha az olan bir değere sahip çağrıldığında 1 değerini verir. İkinci bölüm daha ilginç ve olarak bilinir Rekürsif Adım . Burada biraz değiştirilmiş parametre (biz 1 ile olarak azaltmak) ile aynı yöntemi çağırmak ve daha sonra n bizim kopyasıyla sonucu çarpın.

İlk karşılaştığımız zaman bu tür kafa o incelemek öğretici yüzden o zaman koşmak nasıl çalıştığını olabilir. Imagine biz FactRec dediğimiz (5). Biz baz duruma göre çekildiği değil, rutin girip yüzden bu hale:

// In FactRec(5)
return 5 * FactRec( 5 - 1 );

// which is
return 5 * FactRec(4);

Biz ise tekrar bekçi maddesi durdurulmaz ve bu yüzden de sonunda 4 parametre ile yöntemini yeniden girmek:

// In FactRec(4)
return 4 * FactRec(3);

aldığımız yukarıda biz dönüş değeri içine bu dönüş değeri yerine ise

// In FactRec(5)
return 5 * (4 * FactRec(3));

Bu size son çözüm bu kadar nasıl elde edildiği biz hızlı izlemek ve aşağı yolda her adımı göstereceğiz bir ipucu vermelidir:

return 5 * (4 * FactRec(3));
return 5 * (4 * (3 * FactRec(2)));
return 5 * (4 * (3 * (2 * FactRec(1))));
return 5 * (4 * (3 * (2 * (1))));

temel durum tetiklendiğinde Bu son ikame olur. Bu noktada, ilk etapta faktöriyellerin tanımına doğrudan denk olan çözmek için basit algrebraic formüle sahiptir.

Ya bir taban durumunda yöntemi sonuçlara her çağrı tetiklenen veya parametreler baz durumda yakın olan aynı yöntemi çağrısı (genellikle yinelemeli çağrı denir) olmak olduğunu fark etmek öğretici var. Bu durum söz konusu değilse o zaman yöntem sonsuza çalışacaktır.

Cevap 06/08/2008 saat 03:54
kaynak kullanıcı

oy
12

Özyineleme kendisini çağıran bir fonksiyonu olan bir sorununun çözülmesidir. Buna iyi bir örnek, bir faktöryel fonksiyonudur. 5 faktöryel, örneğin, 5 * 4 * 3 * 2 * 1. Bu fonksiyon pozitif tamsayılar için C # bu çözer nerede Çarpınım bir matematik problemidir (test edilmemiş - bir hata olabilir).

public int Factorial(int n)
{
    if (n <= 1)
        return 1;

    return n * Factorial(n - 1);
}
Cevap 04/05/2010 saat 12:29
kaynak kullanıcı

oy
9

Bir düşünün eski, iyi bilinen sorunu :

Matematikte, büyük ortak böleni iki veya daha fazla sıfırdan farklı tamsayılar (gcd) ..., kalansız numaralarını böler büyük pozitif tam sayıdır.

GCD'nın tanımı şaşırtıcı derecede basit:

gcd tanımı

mod burada modül operatörü (yani, tam sayı bölme işlemi).

İngilizcede bu tanım herhangi bir sayı ve sıfır en büyük ortak böleni bu sayı ve iki sayı en büyük ortak böleni olduğunu söylüyor m ve n en büyük ortak böleni olan n ve bölünmesi sonucu kalan m tarafından n .

Bu işler neden bilmek istiyorsanız, Wikipedia makalesine bakın Öklid algoritması .

Bir örnek olarak gcd (10, 8) hesaplamak olsun. Her adım, kendinden öncekini birine eşittir:

  1. gcd (10, 8)
  2. gcd (10, 10 mod 8)
  3. gcd (8, 2)
  4. gcd (8, 8 mod 2)
  5. gcd (2, 0)
  6. 2

İlk adımda, 8 eşit değildir sıfır yapar, bu nedenle tanımlama ikinci bölümü de geçerlidir. 8 adım 3 'de 2 bir geri kalan kısmı ile bir kez 10 gider 10 mod 8 = 2 için, ikinci bölüm bir daha geçerli olmakla birlikte, bu kez 8 mod 2 = 0 2, çünkü bölme 8 hiç artan kalmaksızın. 5. adımda, ikinci argüman 0, bu nedenle cevap 2'dir.

Eğer gcd eşittir sol ve sağ taraflarında imzalamak hem göründüğünü fark ettiniz mi? Bir matematikçi Eğer tanımlarken ifade çünkü bu tanım özyinelemeli olduğunu söyleyebilirim nükseder onun tanımının içinde.

Özyineli tanımlamalar zarif olma eğilimindedirler. Örneğin, bir liste toplamı için yinelemeli bir tanımıdır

sum l =
    if empty(l)
        return 0
    else
        return head(l) + sum(tail(l))

nerede headbir listedeki ilk unsurdur ve taillistenin geri kalanı. Not sumsonunda tanımı içinde tekrarlanır.

Belki yerine listesindeki maksimum değeri tercih ediyorum:

max l =
    if empty(l)
        error
    elsif length(l) = 1
        return head(l)
    else
        tailmax = max(tail(l))
        if head(l) > tailmax
            return head(l)
        else
            return tailmax

Sen bir dizi ilavede çevirmek için yinelemeli negatif olmayan tamsayılar çoğalmasını tanımlayabilirsiniz:

a * b =
    if b = 0
        return 0
    else
        return a + (a * (b - 1))

mantıklı değil eklemeler bir dizi çarpma dönüştürülmesi hakkında böyle biraz nasıl çalıştığını görmek için birkaç basit örnekler genişleyen deneyin.

Sıralama Birleştirme güzel özyinelemeli bir tanıma sahip:

sort(l) =
    if empty(l) or length(l) = 1
        return l
    else
        (left,right) = split l
        return merge(sort(left), sort(right))

Eğer aramaya ne biliyorsanız özyineli tanımlamalar çevresinde bulunmaktadır. Bu tanımlardan çok basit baz durumlarda, sahip Fark nasıl mesela , gcd (m, 0) m =. Uzakta probleme özyinelemeli vakalar whittle kolay cevapları inmek için.

Bu anlayışla, artık diğer algoritmalar takdir özyineleme üzerinde Wikipedia'nın makalesinde !

Cevap 04/05/2010 saat 14:58
kaynak kullanıcı

oy
9

Yineleme orijinal soruna cevap formüle bu sonucu artı başka bir hesaplama kullanarak, daha sonra bir sorun daha küçük bir versiyonu çözme ve bir sorunu çözen bir yöntemi ifade eder. çözmesi önemsiz bir "taban durum" ulaşıncaya kadar Çoğu zaman, daha küçük bir versiyonunu çözme sürecinde, yöntem, vb sorunun henüz küçük bir versiyonu çözmek ve edecektir.

Örneğin, sayısı için bir çarpınımını hesaplamak için X, tek olarak temsil edebilir X times the factorial of X-1. Böylece yöntem "recurses" faktöriyelini bulmak X-1ve sonra tarafından elinizde ne varsa çarpar Xnihai yanıt vermek. Tabii ki, faktöriyelini bulmak için X-1ilk faktöriyelini hesaplarız, X-2vb, vb. Baz durumda olacaktır Xgeri dönmek için bilir, bu durumda, 0 ya da 1'dir 1itibaren 0! = 1! = 1.

Cevap 04/05/2010 saat 12:26
kaynak kullanıcı

oy
9
  1. kendisini çağıran fonksiyon
  2. bir fonksiyonu olabilir zaman (kolayca) basit işlem ayrıca sorun bazı küçük bölümü üzerinde aynı işlevi ayrılmıştır. Bunun o özyineleme için iyi bir aday yapar, daha doğrusu, demeliyim.
  3. Onlar yapar!

kanonik örnek benziyor faktöryel geçerli:

int fact(int a) 
{
  if(a==1)
    return 1;

  return a*fact(a-1);
}

Genel olarak, tekrarlama hızlı ve bazı sorunları muzdarip olabilir (yığın taşması kimseyi?) (özyinelemeli fonksiyonlar küçük olma eğilimindedir, çünkü işlev çağrısı havai, yukarıya bakınız yüksek olma eğilimindedir) zorunlu değildir. Bazıları önemsiz olmayan durumlarda 'doğru' almak zor olma eğilimi ama cidden o içine almayın diyorum. Bazı durumlarda, tekrarlama en mantıklı ve belirli bir işlevi yazmak için en şık ve net yoldur. Bazı diller özyinelemeli çözümler lehine ve (LISP akla geliyor) çok daha onları optimize unutulmamalıdır.

Cevap 06/08/2008 saat 03:35
kaynak kullanıcı

oy
7

Bir yinelemeli fonksiyonu kendisini çağıran biridir. Bunun bir ağaç yapısı baştan bir başa kullanmak buldum en yaygın nedeni. Onay kutularını bir TreeView'i varsa Örneğin, ben bu (pseudocode) gibi bir şey olurdu "bütün kontrol" butonuna isteyebilirsiniz (yeni bir program, "yüklemeye özellikleri seçin" sayfa yüklemesini düşünüyorum):

function cmdCheckAllClick {
    checkRecursively(TreeView1.RootNode);
}

function checkRecursively(Node n) {
    n.Checked = True;
    foreach ( n.Children as child ) {
        checkRecursively(child);
    }
}

Yani o düğümün çocuklarının her biri için kendisini çağıran, checkRecursively öncelikle geçirilir düğümü kontrol ettiğinden görebilirsiniz.

Sen yineleme ile biraz dikkatli olmak gerekiyor. Eğer sonsuz özyinelemeli döngü içine almak, bir yığın taşması istisna alacak :)

Ben uygun insanlar kullanmayın için bir neden düşünemiyorum. Bazı durumlarda, ve diğerlerinde yararlıdır.

İlginç bir tekniktir, çünkü bazı kodlayıcılar belki gerçek gerekçe olmadan, daha sık olması gerektiği daha bunu kullanarak sonuna düşünüyorum. Bu, bazı çevrelerde özyineleme kötü bir isim vermiştir.

Cevap 06/08/2008 saat 03:44
kaynak kullanıcı

oy
5

Yineleme, doğrudan veya dolaylı olarak kendisini referans bir ifadedir.

Basit bir örnek olarak özyinelemeli kısaltmalar düşünün:

  • GNU açılımı GNU Not Unix
  • PHP açılımı PHP: Hypertext Preprocessor
  • YAML açılımı YAML Dili Biçimlendirme değil mi
  • ŞARAP açılımı Şarap bir emülatör Değildir
  • VISA açılımı Visa International Service Association

Wikipedia'da fazla örnek

Cevap 04/05/2010 saat 12:56
kaynak kullanıcı

oy
5

İşte basit bir örnek: Bir sette kaç unsurlar. (Orada bir şeyler saymak için daha iyi yollar vardır, ama bu güzel bir basit özyinelemeli örnektir.)

İlk olarak, iki kural gerekir:

  1. dizi boşsa, sette öğelerin sayısı sıfır (yaa!) 'dir.
  2. seti boş değilse, sayım bir artı bir madde kaldırıldıktan sonra sette öğelerin sayısıdır.

[Xxx]: Eğer böyle bir set olduğunu varsayalım. orada kaç nesne sayalım.

  1. set [xxx] boş değil ki, bu yüzden biz [xx] (yani biz bir öğe kaldırıldı) öğelerin sayısı bir artı öğelerin sayısıdır kuralı 2. geçerlidir.
  2. set [xx], bu yüzden tekrar kural 2 geçerlidir: [x] öğelerden biri + sayıya.
  3. [] Öğelerden biri + sayı: set hala kural 2 maçları [x] vardır.
  4. Şimdi seti [], kural 1 maçları hangi: sayımı sıfırdır!
  5. Biz (0), biz çözebilir 4. adımda cevabını bilmek Şimdi bu adımı 3 (1 + 0)
  6. Aynı şekilde, şimdi (1), biz çözebilir 3. adımda cevabını biliyoruz ki adım 2 (1 + 1)
  7. Ve nihayet şimdi biz adım 2 (2) 'de cevabı biliyoruz, [xxx], 3. Yaşasın olan 1. adımı (1 + 2) çözmek ve öğelerin sayısı elde edebilir!

Biz bu şekilde temsil edebilir:

count of [x x x] = 1 + count of [x x]
                 = 1 + (1 + count of [x])
                 = 1 + (1 + (1 + count of []))
                 = 1 + (1 + (1 + 0)))
                 = 1 + (1 + (1))
                 = 1 + (2)
                 = 3

Bir özyinelemeli çözümü uygularken, genellikle en az 2 kuralları vardır:

  • temeli, sahip ne olur devletler basit vaka tüm verilerinizi "tükenmiş". Bu genellikle "Eğer sürecine veri bozukluğu varsa, cevap X" bazı varyasyon
  • Hala veri var ne olur devletler özyinelemeli kuralı,. Bu genellikle diyor kural mı olduğunu "veri daha küçük set yapmak ve daha küçük veri setine kurallarınızı yeniden uygulamak için bir şeyler yapmak."

Biz pseudocode yukarıdaki çevirirseniz, şunu elde ederiz:

numberOfItems(set)
    if set is empty
        return 0
    else
        remove 1 item from set
        return 1 + numberOfItems(set)

çok diğer insanların kapsayacak eminim daha yararlı örnekler (örneğin, bir ağaç geçme) var.

Cevap 06/08/2008 saat 04:12
kaynak kullanıcı

oy
5

Özyineleme Bu kadar üzerinde büyük şey daha da küçük sürümü ve her biri bu büyük bir şey daha küçük sürümleri yapılmış demektir büyük bir şeyle uğraşıyoruz "fraktal sorunları", diyoruz en iyi şekilde çalışır. Hiç çapraz veya bir ağaç veya iç içe özdeş yapılar gibi bir şey arama yapmak varsa, özyineleme için iyi bir aday olabilecek bir sorun var.

İnsanlar bir takım nedenlerden için özyinelemeye kaçının:

  1. Fonksiyonel programlama aksine Çoğu insan (ben dahil) prosedürel veya nesne yönelimli programlama konusundaki programlama dişlerini kesti. Bu tür insan için, tekrarlayıcı bir yöntem, (tipik olarak kullanarak döngüleri) daha doğal.

  2. prosedürel veya nesne yönelimli programlama bizim programlama diş kesmek bizler çoğu zaman hata eğilimli olduğu için Özyinelemeyi önlemek için söylendi.

  3. Sık sık tekrarlama yavaş olduğunu söyleniyor. Çağrı ve rutin dönen defalarca döngü daha yavaştır iterek ve haşhaş yığını, bir sürü içerir. Bazı diller diğerlerinden daha bu iyi idare düşünüyorum ve bu diller baskın paradigma prosedürel veya nesne yönelimli olduğu bu büyük olasılıkla değildir.

  4. Ben kullandım programlama dillerinden en az bir çift için, ben onun yığın o derin olmadığı için belirli bir derinlikten sonra alırsa Özyinelemeyi kullanmamayı öneriler işitme hatırlıyorum.

Cevap 06/08/2008 saat 04:12
kaynak kullanıcı

oy
4

kendini çağrı 1. Eğer) bir yöntem olup yinelemeli olduğu; ya doğrudan:

void f() {
   ... f() ... 
}

veya dolaylı:

void f() {
    ... g() ...
}

void g() {
   ... f() ...
}

2.) zaman özyinelemeye kullanımı

Q: Does using recursion usually make your code faster? 
A: No.
Q: Does using recursion usually use less memory? 
A: No.
Q: Then why use recursion? 
A: It sometimes makes your code much simpler!

o yinelemeli kod yazmak çok karmaşık olduğu zaman 3.) İnsanlar özyinelemeye kullanın. Örneğin, ön siparişe gibi ağaç geçişi teknikleri, postorder hem iteratif ve özyinelemeli yapılabilir. Ama genelde biz basitliği nedeniyle özyinelemeli kullanın.

Cevap 11/03/2014 saat 10:47
kaynak kullanıcı

oy
4

Bir özyinelemeli deyimi, bir girdilerin kombinasyonu ve ne yapmış oldukları gibi bundan sonra ne sürecini tanımlayan hangi biridir.

Örneğin, faktöryel atın:

factorial(6) = 6*5*4*3*2*1

Ama (6) da çarpınımını görmek kolaydır:

6 * factorial(5) = 6*(5*4*3*2*1).

Yani genel olarak:

factorial(n) = n*factorial(n-1)

Tabii ki, özyineleme hakkında Buradaki püf nokta zaten yaptıklarından açısından şeyleri tanımlamak istiyorsanız, başlamak için bazı yer olması gerekir olmasıdır.

Bu örnekte, sadece çarpınımını 1 (1) = tanımlayarak özel bir durumda olun.

Şimdi baştan aşağıya bakın:

factorial(6) = 6*factorial(5)
                   = 6*5*factorial(4)
                   = 6*5*4*factorial(3) = 6*5*4*3*factorial(2) = 6*5*4*3*2*factorial(1) = 6*5*4*3*2*1

Biz faktöriyel (1) = 1 tanımlanan bu yana, "alt" ulaşmaktadır.

Genel konuşmak, özyinelemeli prosedürler iki bölümden oluşur:

Aynı prosedürü yoluyla "zaten bitmiş" kadarıyla kombine yeni girdiler açısından bazı prosedürü tanımlamaktadır 1) özyinelemeli parçası. (örneğin factorial(n) = n*factorial(n-1))

Süreç başlatmak için onu bir yere vererek sonsuza tekrar etmez emin olur 2) Bir baz kısmı (yani factorial(1) = 1)

İlk başta kafanı için biraz kafa karıştırıcı olabilir, ama sadece örnekler bir demet bakmak ve onu hep birlikte gelmelidir olabilir. Eğer kavramının çok daha derin bir anlayış istiyorsanız, matematiksel indüksiyon inceliyoruz. Diğerleri yok iken Ayrıca, bazı diller özyinelemeli aramalar için optimize unutmayın. Size dikkatli olmazsan delicesine yavaş özyinelemeli fonksiyonlar yapmak oldukça kolaydır, ancak çoğu durumda onları ölçülebilir hale getirmek için teknikler de vardır.

Bu yardımcı olur umarım...

Cevap 04/05/2010 saat 14:30
kaynak kullanıcı

oy
4

Bu tanım gibi:
yineleme olarak, rutin bir sorun, kendisinin küçük bir kısmını çözer küçük parçalar halinde bir sorun böler ve daha küçük parçalarının her biri çözmek için çağırır.

Ben de o Recursion Bilgisayar Bilimi kitaplarında kullanılan örnekler eleştiriyor nerede tamamlayın Kanununda özyinelemeye Steve McConnells tartışma gibi.

faktöriyellerinin veya Fibonacci sayıları için özyinelemeye kullanmayın

bilgisayar bilimi kitaplarında ile ilgili bir problem ya yinelenen saçma örnekler sunuyoruz olmasıdır. Tipik örnekler, bir faktöriyel işlem veya Fibonacci dizisi işlem vardır. Özyineleme güçlü bir araçtır ve bu tür durumlarda birinde kullanmak gerçekten aptal. benim için çalışan bir programcı bir çarpınımını hesaplamak için özyinelemeye kullandıysanız, başka birini işe alırdım.

Bunu yükseltmek için çok ilginç bir nokta oldu ve tekrarlama genellikle yanlış anlaşılır bir nedeni olabilir düşündüm.

DÜZENLEME: Bu Dav cevabı bir kazmak değildi - ben bu yayınlanmıştır zaman o cevap görmemişti

Cevap 04/05/2010 saat 12:29
kaynak kullanıcı

oy
3

Örnek olarak: Bir merdiven Bir yinelemeli tanımı: bir merdiven oluşur: - bir tek aşamalı ve bir merdiven (yineleme) - ya da sadece tek bir adım (sonlandırma)

Cevap 04/05/2010 saat 14:34
kaynak kullanıcı

oy
3

Eh, bu da sahip oldukça iyi bir tanım bu. Ve wikipedia da iyi bir tanımı vardır. Bu yüzden senin için başka bir (muhtemelen daha kötü) tanımını ekleyeceğiz.

insanlar "özyineleme" söz ettiğimizde, genellikle onun çalışma ile yapılana kadar tekrar tekrar kendisini çağıran onlar yazdım bir fonksiyonu bahsediyoruz. veri yapılarındaki hiyerarşileri geçme zaman Özyineleme yararlı olabilir.

Cevap 04/05/2010 saat 12:27
kaynak kullanıcı

oy
3

Bir sorun çözülecek özyineleme için: hiçbir şey, bitti.
Açık bir problem üzerinde Recurse: Bir sonraki adımı, daha sonra geri kalanı üzerinde Recurse.

Cevap 06/08/2008 saat 04:32
kaynak kullanıcı

oy
2

(Görünümü veya bakış performans noktasının algoritma doğruluğu açısından yani değil) Bu eski bir sorudur ama bakış lojistik açıdan bir cevap eklemek istiyorum.

Ben iş için Java kullanın ve Java iç içe işlevi desteklemez. Ben Özyinelemeyi yapmak istiyorsanız Gibi, ben (benim kod Java'nın bürokratik yönetimine karşı tümsekler sayesinde ayakta durmaktadır) harici işlev tanımlamak gerekebilir, yoksa (gerçekten yapmak nefret) tamamen kod refactor gerekebilir.

Yineleme kendisi esas itibarı ile, bir yığın işlemdir, çünkü böylece, genellikle, bunun yerine özyinelemeye ve kullanım yığın işlemi önlemek.

Cevap 30/08/2014 saat 11:09
kaynak kullanıcı

oy
2

Bir özyinelemeli fonksiyon kendisine bir çağrı içeren bir fonksiyondur. Bir geriye dönüşlü yapı tek başına bir örneğini içeren bir yapı olup. Bir özyinelemeli sınıf olarak ikisini birleştirebilirsiniz. Bir özyinelemeli öğenin anahtar bölümü kendi başına bir örneği / çağrıyı içeren olmasıdır.

birbirine bakan iki ayna düşünün. Biz yaptıkları düzgün sonsuzluk etkisini gördüm. Her bir yansıma kendisinin bir yansıma içeren ayna yineleme olup, vb bir ayna başka bir örneği içinde yer alan bir ayna, bir örneğidir.

Bir ikili arama ağacı özyineleme iyi bir programlama örneğidir. Yapı, bir düğüm 2 örneklerini içeren her bir düğüm ile özyinelemeli. İkili arama ağaç üzerinde çalışmak için fonksiyonlar da tekrar eder.

Cevap 04/05/2010 saat 17:46
kaynak kullanıcı

oy
2

Düz İngilizce: Eğer 3 şey yapabilirsiniz varsayalım:

  1. bir elma alın
  2. taksitli işaretleri not edin
  3. taksitli işaretleri sayın

Bir masaya önünüzde bir sürü elma var ve kaç tane elma bilmek istiyorum.

start
  Is the table empty?
  yes: Count the tally marks and cheer like it's your birthday!
  no:  Take 1 apple and put it aside
       Write down a tally mark
       goto start

bitirdiniz kadar aynı şeyi tekrar işlemi tekrarlama denir.

Bunun Aradığınız "düz ingilizce" cevabı umut!

Cevap 04/05/2010 saat 14:09
kaynak kullanıcı

oy
1

özyineleme basit tanımıyla "kendini referans" dır. kendisi belirtmektedir bir fonksiyon, örneğin, kendisi özyinelemeli çağırır. Akılda tutulması gereken en önemli şey, bir özyinelemeli fonksiyon, bir "taban durum" var doğrudur bunu neden olursa kendisini aramak ve böylece özyinelemeye sonlandırmak için değil bir koşulu yani gerektiğidir. Aksi takdirde sonsuz yinelemeye sahip olacaktır:

yineleme http://cart.kolix.de/wp-content/uploads/2009/12/infinite-recursion.jpg

Cevap 04/05/2010 saat 17:10
kaynak kullanıcı

oy
1

Eğer kendini kullanan bir operasyon olduğunda Özyineleme olduğunu. Muhtemelen, bir durak noktası olacaktır, aksi takdirde sonsuza kadar gider.

Diyelim ki sözlükte Bir kelimeyi bulmak istediğimizi varsayalım. Sen emrinde "bak-up" adı verilen bir operasyon var.

Arkadaşınız "Şu anda gerçekten biraz puding kadar kaşık olabilir!" Diyor Onun ne anlama geldiğini bilmiyorum, bu yüzden sözlükte "kaşık" yukarı baktığında o böyle bir şey okur:

Kaşık: isim - uçta yuvarlak kepçe sahip bir alet. Kaşık: arkadan yakından kucaklamak için -: - fiil fiil şey kaşık bir kaşık kullanmayı

Şimdi, gerçekten İngilizce ile iyi olmadıklarını olmak, bu doğru yönde işaret, ancak fazla bilgiye ihtiyacımız var. Yani bazı daha fazla bilgi için aranacak "kap" ve "Ebeveyn" seçeneğini seçin.

Kucaklamak: - fiil Gereçler yatmak: isim - bir araç, sık sık bir yeme malzemesi

Hey! Sen Snuggling ne olduğunu biliyorum ve puding ile ilgisi yoktur. Ayrıca puding yemek bir şey olduğunu biliyoruz, bu yüzden şimdi mantıklı. Arkadaşınız bir kaşıkla puding yemek istiyorum gerekir.

Tamam, tamam, (belki kötü) ya yinelenen iki ana parça bu çok topal örnek, ama göstermektedir. 1) kendisi kullanır. Bu örnekte, bunu anlamak kadar gerçekten anlamlı bir kelime bakmadım ve bu daha fazla kelime ararken anlamına gelebilir. Bu ikisini işaret etmek bizi, 2) Bir yerlere durur. Bu baz durumunda çeşit olması gerekiyor. Aksi takdirde, sadece muhtemelen çok yararlı değildir sözlükte, her kelimeyi ararken bitirmek istiyorum. Bizim temel durumdaki daha önce ve anlamadı ne yaptı arasında bir bağlantı kurmak için yeterli bilgi var oldu.

5 faktöriyel (120 olan) 1 * 2 * 3 * 4 * 5 olduğu verdi geleneksel örnek faktörlüdür. temel durum 0 (ya da 1, olarak) olabilir. Yani, herhangi bir tam sayı n için, aşağıdakileri yapmanız

0 n eşittir? Aksi 1 geri n x (n-1 faktöriyel) dönüş

en (biz 1 * 2 * 3 * 4 = 24 olduğu önceden bilmek) 4 örnekle yapalım.

4 faktöryel ... 0 olur? hayır, bu yüzden 3 * faktöryel 4 olmalı ama 3 faktöryel ne? öyle 3 * 2 2 faktöriyele ait faktöryel * 1 1 faktöriyele ait faktöryel * 1'dir 0 faktöryel ve 0 faktöryel BİLMEK 2'dir! :-D durum 1, bu ... 1 tanımı faktöryel * 1 oldu 0, faktöryel 1'dir yani 1 * 1 = 1 faktöryel 2 * böylece ... * 2 1 oldu 1, faktöryel 2'dir 4 (son olarak !!) 4 * olarak 3 faktör, 6, ... 4 * 6 yani 3 * 2 = 6 faktörlü 3 1 = 2 faktör ... * 2 olduğu, 2, faktör 3'tür 24

Faktoriyel basit bir durumdur "baz durumda ve kendisini kullanır".

Şimdi, biz hala 100 faktöriyelini isteseydik buna yükü bir sürü var olabilir ... 0'a tüm yol aşağı gitmek zorunda kalacak ... tüm yol aşağı 4 faktöriyele üzerinde çalışıyorlardı dikkat edin. Biz sözlükte aramak için bir karanlık kelime bulmak eğer biz aşina bir bağlantı bulana kadar aynı şekilde, bu diğer kelime ve bağlam ipuçlarını tarama ararken sürebileceğini. Yinelemeli yöntemler yollarını iş için uzun zaman alabilir. bunların doğru kullanılır ve anlaşılan yaparken Ancak, bunlar işin içinden çıkılmaz şaşırtıcı derecede basit yapabilirsiniz.

Cevap 04/05/2010 saat 17:04
kaynak kullanıcı

oy
1

Pek çok sorunlar adet iki tipte düşünülebilir:

  1. Sadece onlara bakarak çözebilir temel şeylerdir Baz durumlarda, ve
  2. daha küçük parçalara (ilköğretim veya başka bir şekilde) dışında daha büyük bir sorun kurmak Rekürsif vakalar.

Yani bir özyinelemeli fonksiyon nedir? Eğer kendisi açısından tanımlanmış bir fonksiyonu var nerede Eh, bu doğrudan veya dolaylı olarak bu. doğrudan taban davaları çözmek ve içinde gömülü problemin küçük parçalarını çözmek için tekrarlanan aramalara kullanarak özyinelemeli davalarına: Eğer yukarıda açıklanan türden sorunları için mantıklı olduğunu fark kadar Tamam, bu saçma geliyor.

Eğer bir ağaç uğraşırken çağırmayı bir (veya çok bunun gibi kokuyor şey) gereken yere gerçekten klasik bir örneğidir. Ağacın yaprakları taban harf ve dalları özyinelemeli vaka bulunmaktadır. (Psödo-C.)

struct Tree {
    int leaf;
    Tree *leftBranch;
    Tree *rightBranch;
};

sırayla bu yazdırmanın en basit yolu Özyinelemeyi kullanmaktır:

function printTreeInOrder(Tree *tree) {
    if (tree->leftBranch) {
        printTreeInOrder(tree->leftBranch);
    }
    print(tree->leaf);
    if (tree->rightBranch) {
        printTreeInOrder(tree->rightBranch);
    }
}

kristal berraklığında var, çünkü o işe yarayacak görmek ölü kolaydır. (Özyinesiz eşdeğerdir oldukça çok daha karmaşık, şeylerin listesini yönetmek için dahili olarak bir yığın yapısı gerektiren işlemek için.) Eh, kimse elbette dairesel bir bağlantı yapıldığını varsayarak.

Matematiksel olarak, terbiye olduğunu Özyinelemeyi gösteren hile argümanlar boyutu için bir metrik bulmaya odaklanmaktır. Bizim ağaç Örneğin, en kolay metrik geçerli düğümün altındaki ağacın maksimum derinliktir. Yaprakların anda, sıfır var. şubeden ile sadece vs. biri Sonra sadece kesinlikle fonksiyon ağacı işleyebilmek için çağrılır olduğunu argümanlar büyüklüğüne dizisi sipariş etti gösterebilirse, bunun altında bırakır; özyinelemeli aramaları argümanlar her zaman genel çağrısına argüman daha metrik anlamında "daha az" dır. kesinlikle azalan kardinal metrik ile, sıralama.

Bu sonsuz yinelemeye sahip olmak da mümkündür. Bu yığın patlarsa çünkü çalışmaz dağınık ve pek çok dilde bu. o çalışır Nerede (dil motor fonksiyon nedense dönüp yığının tutulmasını uzağa optimize edilmesi mümkün olmadığı belirlenirken edilmelidir Zor şeyler genelde;. kuyruk özyineleme Bunu yapmanın sadece en önemsiz yoludur .)

Cevap 04/05/2010 saat 16:29
kaynak kullanıcı

oy
1

Yineleme başına açısından bir fonksiyon, bir dizi veya bir algoritmayı tanımlamak tekniğidir.

Örneğin

n! = n(n-1)(n-2)(n-3)...........*3*2*1

Şimdi yinelemeli olarak tanımlanabilir: -

n! = n(n-1)!   for n>=1

Bir işlev veya yöntem defalarca kendisini çağırdığında bazı özel koşul yerine alana kadar programlama açısından, bu süreç Özyineleme denir. Ama bir sonlandırma koşulu ve işlev olmalıdır veya yöntem yok sonsuz bir döngü içine girmelidir.

Cevap 04/05/2010 saat 16:22
kaynak kullanıcı

oy
1

işlem yineleme tek bir fonksiyon (yöntem olup, işlem veya blok) çağırma normal geri dönmesinin ardından bir sonucu veya bir yan etkiyi hesaplamak için kullanılan bir tekniktir.

tanım olarak özyinelemeli işlevi, (diğer fonksiyonlar yoluyla) ya doğrudan ya da dolaylı olarak kendini çağırmak yeteneği bir çıkış durumuna bağlı olarak ya da şartların yerine olmamak olmalıdır. Bir çıkış koşulu da en arayana özellikle çağırma döner araya geldi ise. ilk başlatma hangi zaman istenen sonucu ya da yan etki mevcut olacak, döndürülen kadar devam eder.

Bir örnek olarak, burada (Scala Quicksort algoritmasını gerçekleştirmek için bir fonksiyon var Scala için Vikipedi girişi kopyalanmış )

def qsort: List[Int] => List[Int] = {
  case Nil => Nil
  case pivot :: tail =>
    val (smaller, rest) = tail.partition(_ < pivot)
    qsort(smaller) ::: pivot :: qsort(rest)
}

Bu durumda çıkış koşulu boş listedir.

Cevap 04/05/2010 saat 15:14
kaynak kullanıcı

oy
1

fonksiyon kendisini aramak veya kendi tanımını kullanın.

Cevap 04/05/2010 saat 14:59
kaynak kullanıcı

oy
1

Herhangi algoritma sergileyen yapısal temelde veri türü her durum için bir vaka ile bir switch deyimi oluşuyorsa bir veri türü özyinelemeyi.

Örneğin, bir türüne çalışırken

  tree = null 
       | leaf(value:integer) 
       | node(left: tree, right:tree)

yapısal bir dönüşümlü algoritma formu olurdu

 function computeSomething(x : tree) =
   if x is null: base case
   if x is leaf: do something with x.value
   if x is node: do something with x.left,
                 do something with x.right,
                 combine the results

Bu gerçekten bir veri yapısı üzerinde çalışan herhangi olarak algoritma yazmak için en belirgin yoldur.

şimdi, tamsayılar baktığınızda (iyi, doğal sayılar) Peano aksiyomlar kullanılarak tanımlanan

 integer = 0 | succ(integer)

Eğer tamsayılar üzerinde yapısal bir özyinelemeli algoritması şöyle görüyoruz

 function computeSomething(x : integer) =
   if x is 0 : base case
   if x is succ(prev) : do something with prev

Çok-çukurlu bilinen faktör fonksiyon bu formun en basit örnekte hakkındadır.

Cevap 04/05/2010 saat 14:53
kaynak kullanıcı

oy
1

Bence biriyle kabul ederse hey, üzgünüm, sadece düz İngilizce Özyinelemeyi açıklamaya çalışıyorum.

Jack, John ve Morgan - üç yöneticileri olduğunu varsayalım. Her yöneticisini 300 $ verecek ve onu mal olacağını bilmek istiyorum edilir 5. - 3 ve Morgan - Jack 2 programcıları, John yönetir. Cevap açıktır - ama ne Morgan-ler çalışanlarının 2 eğer yöneticileri de vardır?

BURADA tekrarlama geliyor. Eğer hiyerarşinin üst kısmından başlayın. yazlık maliyeti 0 $ 'dır. Onun çalışanları gibi herhangi yöneticisi varsa Sonra kontrol Jack ile başlar. Eğer onlar çalışanlar ve benzeri gibi herhangi yöneticileri var olmadığını kontrol edilmektedir bunlardan herhangi bulursanız. yazlık maliyeti bir yönetici bulmak her zaman 300 $ ekleyin. Jack ile bittiğinde, Morgan sonra John, onun çalışanlara gidip.

Sen kaç tane yönetici biliyor ve kaç Bütçe harcama olabilir ama, bir cevap almadan önce gidecek ne kadar çevrimler, asla bilemeyeceğim.

Özyineleme sırasıyla dalları ve yaprakları denilen ebeveynler ve çocuklar ile, bir ağaçtır. Eğer bir yineleme algoritması kullandığınızda, az ya da çok bilinçli verilerden bir ağaç inşa bulunmaktadır.

Cevap 04/05/2010 saat 13:50
kaynak kullanıcı

oy
1

Düz İngilizce, tekrarlama tekrar tekrar Someting tekrarlamak anlamına gelir.

Programlamada bir örnek kendi içinde işlevini çağırarak taşımaktadır.

Bir sayının çarpınımını hesaplama aşağıdaki örnekte bak:

public int fact(int n)
{
    if (n==0) return 1;
    else return n*fact(n-1)
}
Cevap 04/05/2010 saat 13:48
kaynak kullanıcı

oy
1

Özyineleme iself bir yöntem çağrısı belli görevi gerçekleştirmek için muktedir bir süreçtir. Bu kodun Redundency azaltır. Bu sonsuz bir döngü oluşturmayı engeller - En recurssive işlevler veya yöntemler yani dediğimiz bir koşul gerçekleştiğinde kendisini aramasını durdurmak recussive kırmak için bir condifiton olması gerekir. Tüm fonksiyonlar yinelemeli kullanılmak üzere uygundur.

Cevap 04/05/2010 saat 13:42
kaynak kullanıcı

oy
1

onun bir yolu üzerinde ve her opsiyon kullanıldığını süresiz böyle aşırı şeyler yapmak.

Örneğin size sayfa 1 tüm bağlantıları alınca ilk sayfasında bulunan bağlantıların her birini tüm bağlantıları almak isteyeceksiniz çünkü recursions yapmak isteyecektir bir html sayfasındaki tüm bağlantıları almak istiyorsa. Daha sonra NewPage için her bağlantı için o bağlantılar isteyeceklerdir vb ... diğer bir deyişle kendisi içerden kendisini çağıran bir işlevdir.

Bunu yaparken ne zaman duracağını bilmek için bir yol gerekir ya da döngü sayısını izlemek için işleve bir tamsayı param eklemek böylece başka sonsuz bir döngü içinde olacaktır.

c # böyle bir şey olacak:

private void findlinks(string URL, int reccursiveCycleNumb)    {
   if (reccursiveCycleNumb == 0)
        {
            return;
        }

        //recursive action here
        foreach (LinkItem i in LinkFinder.Find(URL))
        {
            //see what links are being caught...
            lblResults.Text += i.Href + "<BR>";

            findlinks(i.Href, reccursiveCycleNumb - 1);
        }

        reccursiveCycleNumb -= reccursiveCycleNumb;
}
Cevap 04/05/2010 saat 13:02
kaynak kullanıcı

oy
1

"Bir çekiç varsa, her şey bir çivi gibi görünmesi."

Özyineleme için bir sorun çözme stratejisidir büyük her sadece, aynı çekiçle her seferinde "tek ve daha büyük şeyin içine 2 küçük işler" adım problemler.

Örnek

Masanızın 1024 kağıtların dağınık karmaşa ile kaplıdır varsayalım. Nasıl özyineleme kullanılarak karmaşa kağıtları biri düzgün, temiz yığın yapabilirim?

  1. Böl: Her "yığın" sadece bir levha var ve bu yüzden, tüm sayfaları yayıldı.
  2. Fethetmek:
    1. bir başka tabakanın üstünde her levha koyarak, etrafında gidin. Artık 2 yığınlar var.
    2. başka bir 2-yığının üstüne her 2 yığını koyarak, etrafında gidin. Artık 4 destesi var.
    3. Başka 4-yığının üstüne her biri 4-yığını koyarak, etrafında gidin. Artık 8 yığınlar var.
    4. ... durmadan ...
    5. Artık 1024 levhalardan birinin büyük yığınını var!

Bu bir yana (kesinlikle gerekli değil) her şeyi saymaktan, oldukça sezgisel olduğuna dikkat edin. Sen gerçekte, aşağı 1 yapraklık yığınlar kadar gitmek olmayabilir, ama sen ve hala çalışmaya devam eder başladı. önemli kısmı çekiç: ne kadar büyük ya yığını kollarına ile her zaman daha büyük bir yığın yapmak için üst üste bir yığın koyabilirsiniz ve (mâkul) önemli değildir.

Cevap 04/05/2010 saat 12:54
kaynak kullanıcı

oy
1

Bir görevi başarmak üzere Özyineleme o programlama için uygulandığı gibi temelde farklı parametrelerle, (kendi içinde) kendi tanımı içinden bir işlev çağrısında bulunuyor.

Cevap 04/05/2010 saat 12:25
kaynak kullanıcı

oy
1

Sen her zaman bir ağaç yapısına sahip kullanmak istiyorum. Bu XML okumak çok faydalıdır.

Cevap 21/08/2008 saat 14:18
kaynak kullanıcı

oy
1

O mesela Özyinelemeyi kullanılan niye Mario, ben .. her giriş yoluyla Neden sadece döngü anlamıyorum? Böyle bir şey:

String ArrangeString(TStringList* items, String separator)
{
    String result = items->Strings[0];

    for (int position=1; position < items->count; position++) {
        result += separator + items->Strings[position];
    }

    return result;
}

Yukarıdaki yöntemi daha hızlı olacak ve daha basittir ederim. Basit bir döngü yerine Özyinelemeyi kullanmaya gerek yoktur. Ben tekrarlama kötü bir rap alır neden örneklerinden bu tür olduğunu düşünüyorum. Hatta kanonik faktöryel işlevi örneği daha iyi bir döngü ile uygulanmaktadır.

Cevap 06/08/2008 saat 04:19
kaynak kullanıcı

oy
0

Aslında faktöriyele için daha iyi özyinelemeli çözüm olmalıdır:

int factorial_accumulate(int n, int accum) {
    return (n < 2 ? accum : factorial_accumulate(n - 1, n * accum));
}

int factorial(int n) {
    return factorial_accumulate(n, 1);
}

Bu sürüm olduğundan özyinelemeli Kuyruk

Cevap 21/08/2008 saat 14:39
kaynak kullanıcı

oy
0

Ben Özyinelemeyi kullanın. (arada, bilmiyorum) bir CS derecesi ... sahip ilgisi var ne

Yaygın kullanımlar Ben bulduk:

  1. site haritaları - belge köküne başlayan dosya sistemi üzerinden recurse
  2. örümcekler - Bir web sitesi aracılığıyla tarama e-posta adresini, bağlantılar, vb bulmak için
  3. ?
Cevap 06/08/2008 saat 04:13
kaynak kullanıcı

oy
0

Aralarında bir ayırıcı ile dizeleri listesini bitiştirmek için bir özyinelemeli fonksiyon oluşturduk. Ben 'gibi alanlara listesini ileterek SQL ifadeleri oluşturmak için çoğunlukla kullanmak öğeleri ' ve ' virgül + uzay ayırıcı olarak'. İşte fonksiyonu (Bazı Borland Builder yerel veri türlerini kullanır, ancak başka bir ortam uyacak şekilde adapte edilebilir) var:

String ArrangeString(TStringList* items, int position, String separator)
{
  String result;

  result = items->Strings[position];

  if (position <= items->Count)
    result += separator + ArrangeString(items, position + 1, separator);

  return result;
}

Ben bu şekilde diyoruz:

String columnsList;
columnsList = ArrangeString(columns, 0, ", ");

Bir dizi adı 'var düşünün alanları içindeki bu verilerle': ' albumName ', ' ReleaseDate ', ' labelId '. Sonra işlevini çağırır:

ArrangeString(fields, 0, ", ");

Işlev çalışmaya başlar olarak, değişken ' sonuç ' 'dizinin pozisyonunun 0 değerini alır albumName '.

o aşar pozisyon sonuncusu ise Sonra denetler. öyle değil gibi, o zaman ayırıcı ve Tanrı oh bu aynı işlevi, bir fonksiyonun sonucunu ile sonuç birleştirirstrFil. Ama bu sefer, bunu kontrol, bu pozisyona 1 ekleyerek kendisini diyoruz.

ArrangeString(fields, 1, ", ");

o pozisyonu ele ediliyor noktası sonuncusu IS ulaşır, bu nedenle fonksiyon artık birleştirerek değil, listede bu pozisyonda sadece öğesi döndürür verene kadar bir LIFO yığın oluşturarak, tekrar ediyor. Daha sonra yığın geriye birleştirilmiş.

Anladım? Eğer yoksa, bunu açıklamak için başka bir yol var. :O)

Cevap 06/08/2008 saat 04:00
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more