Une fonction récursive est une fonction qui s'appelle elle-même. C'est une approche utile pour résoudre des problèmes qui peuvent être décomposés en sous-problèmes plus petits et similaires à l'original.
Prenons un exemple de calcul de la factorielle d'un nombre entier. La factorielle d'un nombre entier positif n, notée n!, est le produit des entiers de n à 1. Par exemple, 5! = 5 * 4 * 3 * 2 * 1 = 120.
Voici une fonction récursive pour calculer une factorielle en C# :
int Factorielle(int n) {
if (n == 1) { // Cas de base
return 1;
} else { // Appel récursif
return n * Factorielle(n - 1);
}
}- Cas de base : Si
nvaut 1, la fonction retourne 1. C'est ce qui met fin à la récursion. - Appel récursif : Sinon, la fonction s'appelle elle-même avec
n - 1jusqu'à ce que le cas de base soit atteint.
int résultat = Factorielle(5);
Console.WriteLine(résultat); // Affichera 120Factorielle(5)appelleFactorielle(4) * 5Factorielle(4)appelleFactorielle(3) * 4Factorielle(3)appelleFactorielle(2) * 3Factorielle(2)appelleFactorielle(1) * 2Factorielle(1)retourne 1Factorielle(2)retourne1 * 2 = 2Factorielle(3)retourne2 * 3 = 6Factorielle(4)retourne6 * 4 = 24Factorielle(5)retourne24 * 5 = 120
Il est essentiel de toujours prévoir un cas de base dans une fonction récursive pour éviter une récursion infinie, qui entraînerait un plantage du programme.
Si nous oublions d'inclure un cas de base, le programme continue de s'appeler lui-même indéfiniment :
int MauvaiseRecursion(int n) {
return n * MauvaiseRecursion(n - 1); // Pas de cas de base
}Cela entraînera une erreur du type StackOverflowException à cause du dépassement de la pile mémoire.
Voici un exemple d'une fonction récursive pour calculer une puissance a^b :
int Puissance(int a, int b) {
if (b == 0) { // Cas de base
return 1;
} else {
return a * Puissance(a, b - 1); // Appel récursif
}
}- La récursion simplifie le code pour certains problèmes qui ont une structure récursive naturelle, comme les arbres ou les algorithmes de recherche.
- Peut entraîner une utilisation importante de la mémoire si la profondeur de récursion est trop grande.
- Moins efficace que les boucles dans certains cas, car chaque appel de fonction ajoute une nouvelle couche à la pile.
Le nombre de Fibonacci est défini par la suite suivante :
F(0) = 0F(1) = 1F(n) = F(n-1) + F(n-2)pourn >= 2
Implémentez une fonction récursive pour calculer le n-ième nombre de Fibonacci.
Console.WriteLine(Fibonacci(4)); // Affichera 3, car le 4ème nombre de Fibonacci est 3 (0,1,1,2,3)
Console.WriteLine(Fibonacci(6)); // Affichera 8, car le 6ème nombre de Fibonacci est 8 (0,1,1,2,3,5,8)
Console.WriteLine(Fibonacci(10)); // Affichera 55, car le 10ème nombre de Fibonacci est 55 (0,1,1,2,3,5,8,13,21,34,55)Solution
int Fibonacci(int n) {
if (n == 0) {
return 0;
} else if (n == 1) {
return 1;
} else {
return Fibonacci(n - 1) + Fibonacci(n - 2); // Appels récursifs
}
}Ecrivez une fonction récursive SommeTableau qui prend 2 paramètres (un tableau et un entier) et calcule la somme des éléments du tableau. Le second paramètre est la taille du tableau et peut être utilisé pour déterminer le cas de base.
int[] nombres = { 1, 2, 3, 4, 5 };
int somme = SommeTableau(nombres, nombres.Length);
Console.WriteLine(somme); // Affichera 15Solution
int SommeTableau(int[] tableau, int n) {
if (n <= 0) { // Cas de base
return 0;
} else {
return tableau[n - 1] + SommeTableau(tableau, n - 1);
}
}Ecrivez une fonction récursive InverserChaine qui prend une chaîne de caractères en paramètre et renvoie la chaîne inversée.
string chaine = "Hello";
string chaineInverse = InverserChaine(chaine);
Console.WriteLine(chaineInverse); // Affichera "olleH"Solution
string InverserChaine(string chaine) {
if (chaine == "") { // Cas de base
return "";
} else {
return chaine[chaine.Length - 1] + InverserChaine(chaine.Substring(0, chaine.Length - 1));
}
}Ecrivez une fonction récursive EstPalindrome qui prend une chaîne de caractères en paramètre et renvoie true si la chaîne est un palindrome (se lit de la même manière dans les deux sens), false sinon.
Console.WriteLine(EstPalindrome("radar")); // Affichera true
Console.WriteLine(EstPalindrome("hello")); // Affichera falseSolution
bool EstPalindrome(string chaine) {
if (chaine.Length <= 1) { // Cas de base
return true;
} else {
return chaine[0] == chaine[chaine.Length - 1] && EstPalindrome(chaine.Substring(1, chaine.Length - 2));
}
}Ecrivez une fonction récursive SommeChiffres qui prend un entier en paramètre et renvoie la somme de ses chiffres.
Console.WriteLine(SommeChiffres(123)); // Affichera 6 (1 + 2 + 3)
Console.WriteLine(SommeChiffres(456)); // Affichera 15 (4 + 5 + 6)Solution
int SommeChiffres(int n) {
if (n == 0) { // Cas de base
return 0;
} else {
return n % 10 + SommeChiffres(n / 10);
}
}Ecrivez une fonction récursive EstPremier qui prend un entier en paramètre et renvoie true si c'est un nombre premier, false sinon.
Pour rappel, un nombre premier est un entier supérieur à 1 qui n'a aucun diviseur autre que 1 et lui-même.
Console.WriteLine(EstPremier(7)); // Affichera true
Console.WriteLine(EstPremier(10)); // Affichera falseSolution
bool EstPremier(int n, int diviseur = 2) {
if (n <= 2) { // Cas de base
return n == 2;
} else if (n % diviseur == 0) {
return false;
} else if (diviseur * diviseur > n) {
return true;
} else {
return EstPremier(n, diviseur + 1);
}
}Ecrivez une fonction récursive NombreChiffres qui prend un entier en paramètre et renvoie le nombre de chiffres qu'il contient.
Console.WriteLine(NombreChiffres(123)); // Affichera 3
Console.WriteLine(NombreChiffres(4567)); // Affichera 4Solution
int NombreChiffres(int n) {
if (n == 0) { // Cas de base
return 0;
} else {
return 1 + NombreChiffres(n / 10);
}
}