Jest taki stary (z brodą) dowcip że rekurencję się zrozumie jak się zrozumie rekurencję. Problem w tym że śmieją się z tego dowcipu tylko Ci którzy rozumieją rekurencję ;)
A poważnie. Myślę że lepiej rekurencję wytłumaczyć na bardzo prostym przykładzie. Sam tak byłem uczony :)
Jak wiadomo "napis w stylu C", składa się z liter ASCII zakończonych kodem '\0' (czyli znakiem o wartości 0-zero). Jak więc policzyć długość napisu?
Warunek brzegowy to sytuacja gdy napis jest już pusty. Zawiera sam znak 0. Wtedy należy zwrócić wartość licznika który będzie miał wartość 0.
Jeśli jednak zawiera znak "niezerowy", należy inkrementować licznik i wywołać samego siebie ze wskazaniem na następny znak.
Bardzo szkolny przykład:
#include <iostream>
#include <cstdio>
size_t strlen_recur(const char * str, std::size_t counter)
{
if (*str == '\0') {
return counter;
}
return strlen_recur(++str, counter + 1);
}
int main()
{
const char * msg = "Ala ma kota";
std::cout << "Napis: |" << msg << "|, ma długość "
<< strlen_recur(msg, 0) << " znaków.\n";
}
W linijce 8 masz wywołanie rekurencyjne. Funkcja "sama siebie woła".
Teraz jedynie aby łatwiej można wywołać funkcję i ew. nie zapomnieć o zerowaniu licznika, można dodać do niego wartość domyślną. Tu w pełnym brzmieniu:
#include <iostream>
#include <cstdio>
size_t strlen_recur(const char * str, std::size_t counter = 0)
{
if (*str == '\0') {
return counter;
}
return strlen_recur(++str, counter + 1);
}
int main()
{
const char * msg = "Ala ma kota";
std::cout << "Napis: |" << msg << "|, ma długość "
<< strlen_recur(msg) << " znaków.\n";
}
Proponuję teraz przećwiczyć sam sposób programowania na następujących przykładach:
1. Przy przekazaniu do funkcji adresu tablicy i jej długości, zwrócić ilość występujących w niej liczb parzystych.
Podpowiedź: Funkcja licząca będzie miała 3 parametry. Adres pierwszego elementu (np. int *), ilość danych (np. std::size_t ilosc), ilość występujących elementów parzystych (np. std::size_t parzyste_ilosc).
2. Przy przekazaniu do funkcji adresu tablicy i jej długości, wyprowadzić na ekran:
- elementy w kolejności ich występowania
- elementy odwrotnie do kolejności ich występowania
... itd.. (mam tych ćwiczeń oczywiście więcej... )
... rzecz jasna wszystko zrób rekurencyjnie :)