La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

1 La récursion. Nous avons vu qu'un programme est constitué d'un ensemble de fonctions. Il est possible pour une fonction donnée d'appeler une autre fonction.

Présentations similaires


Présentation au sujet: "1 La récursion. Nous avons vu qu'un programme est constitué d'un ensemble de fonctions. Il est possible pour une fonction donnée d'appeler une autre fonction."— Transcription de la présentation:

1 1 La récursion

2 Nous avons vu qu'un programme est constitué d'un ensemble de fonctions. Il est possible pour une fonction donnée d'appeler une autre fonction. Que se passe-t-il si une fonction s'appelle elle- même? C'est ce que l'on appelle la récursion.

3 Question: Écrire un programme qui calcule le nombre de Fibonacci défini comme suit:

4 #include int fibona(int); int main() { cin << n; cout <<le <<n<< ème nombre est; cout << fibona(n); return (0); } int fibona(int n) {int ans; if n < 2 ans = n; else ans = fibona(n-1) + fibona(n-2); return (ans); } Cette fonction est valide: aucune règle n'interdit à une fonction de s'appeler elle- même.

5 Définition: Une procédure est dite récursive si elle fait appel à elle-même (directement ou indirectement).

6 Fonctionnement dune fonction récursive Création dune pile pour la sauvegarde entre autres des paramètres dappels de la procédure

7 Calculer n! Description du problème: Calculer le factorielle d'un nombre entier donné en entrée. Entrée: Un nombre entier plus grand ou égal à 0. Sortie: Un nombre entier.

8 Fonction principale entier n nfact lire n nfact factoriel(n) écrire la factorielle de n est nfact où factoriel satisfait le prototype entier factoriel(entier)

9 Fonction principale entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact où factoriel satisfait le prototype entier factoriel(entier)

10 Analyse de la fonction factoriel 0! = 1 1! = 1 2! = 2*1 = 2 3! = 3*2*1 = 6 4! = 4*3*2*1 = 24 n! = n*(n-1)*(n-2)*…*2*1 = n* (n-1)! 1 si n 1 n!= n * (n-1)! sinon

11 Fonction factoriel Entête: entier factoriel(entier n) Corps: si (n 1) retourner 1 retourner n * factoriel(n-1)

12 Pas-à-pas avec n=4 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact entier n nfact............ n nfact

13 entier n nfact lire n nfact si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact lire n............ 4 n nfact

14 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact si (n < 0) alors écrire entrée négative: n............ 4 n nfact entier

15 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact nfact factoriel(n)............ 4 n nfact entier

16 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact............ 4 4 n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1)

17 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact............ 4 4 n nfact n si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 1

18 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact............ 4 4 n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1)

19 si (n 1) retourner 1 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact 3............ 4 4 n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) n entier

20 si (n 1) retourner 1 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact 3............ 4 4 n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 1 nentier

21 si (n 1) retourner 1 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact 3............ 4 4 n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) n entier

22 si (n 1) retourner 1 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact 3............ 2 4 4 n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 1 retourner n * factoriel(n-1) n n entier

23 si (n 1) retourner 1 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact 3............ 2 4 4 n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 1 retourner n * factoriel(n-1) n n entier si (n 1) retourner 1

24 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact 3............ 2 4 4 n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 1 retourner n * factoriel(n-1) n n entier retourner n * factoriel(n-1)

25 si (n 1) retourner 1 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact 3............ 1 2 4 4 n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 1 retourner n * factoriel(n-1) n n entier si (n 1) retourner 1 retourner n * factoriel(n-1) n entier

26 si (n 1) retourner 1 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact 3............ 1 2 4 4 n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 1 retourner n * factoriel(n-1) n n entier si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 1 n entier

27 si (n 1) retourner 1 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact 3............ 2 4 4 n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 1 retourner n *1 n entier n retourner n * 1

28 si (n 1) retourner 1 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact 3............ 4 4 n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) n entier retourner n * 2

29 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact............ 4 4 n nfact n si (n 1) retourner 1 retourner n * factoriel(n-1) retourner n * 6

30 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact............ 4 24 n nfact entier nfact 24

31 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact............ 4 24 n nfact écrire la factorielle de n est nfact

32 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact............ 4 24 n nfact entier est 24 La factorielle de 4 est 24

33 Comment le faire en C #include int fact(int) /* prototype de la fonction*/ int main(){ int n; cin >> n; if (n < 0) cout <<nombre négatif; else cout << fact(n); return (0); } int fact(int n) /* définition de la fonction*/ { if (n < 2) return (1); else return (n*fact(n-1)); } Test darrêt

34 Le test darrêt La récursion (appels de la fonction à elle- même) doit sarrêter à un moment donné (test darrêt). Autrement, lexécution va continuer indéfinement.

35 Exemple void exemple() { cout << "La recursion\n"; exemple(); }

36 Exemple 2: Lire et afficher un nombre arbitraire d'entiers Description du problème: Lire un entier n suivit de n autres entiers que l'on doit afficher à l'écran. Entrée: Un entiers positif n suivi de n entiers séparés par un ou plusieurs caractères d'espacement. Sortie: n entiers, un par ligne.

37 Exemple Sur l'entrée: 3 45 123 67 le programme doit afficher: 45 123 67

38 Fonction principale entier n lire n copier(n) où copier satisfait le prototype copier(entier)

39 Fonction copier Entête: copier(entier n) Corps: Copier la première valeur Copier les n-1 autres valeurs

40 Fonction copier Entête: copier(entier n) Corps: si (n < 1) retourner Il n'y a rien à lire sinon Copier la première valeur Copier les n-1 autres valeurs

41 Fonction copier Entête: copier(entier n) Corps: entier x si (n < 1) retourner Condition d'arrêt sinon lire x ecrire x copier(n-1)Copier les n-1 valeurs suivantes

42 #include void copier(int); /* prototype de la fopnction */ main(){ int n; cin>>n; copier(n); } void copier(int n){ int x; if (n < 1) return;/* S'il n'y a plus rien a lire. */ cin>>x;/* Copier la premiere valeur. */ cout<<x<<endl; copier(n-1);/* Copier les valeurs suivantes. */ } Comment le faire en C

43 Inverser l'ordre des entiers lus Description du problème: Refaire le problème précédent mais cette fois en affichant les valeurs dans l'ordre inverse. Entrée: Un entiers positif n suivit de n entiers séparés par un ou plusieurs caractères d'espacement. Sortie: n entiers, un par ligne.

44 Exemple Sur l'entrée: 3 45 123 67 le programme doit afficher: 67 123 45

45 Fonction principale entier n lire n invcopier(n) où invcopier satisfait le prototype invcopier(entier)

46 Fonction copier de précédente Entête: copier(entier n) Corps: entier x si (n < 1) retourner Condition d'arrêt sinon lire x ecrire x copier(n-1) Copier les n-1 valeurs suivantes

47 Fonction invcopier Entête: invcopier(entier n) Corps: entier x si (n <= 0) retourner Condition d'arrêt sinon lire xLire la première valeur invcopier(n-1)Copier les n-1 valeurs suivantes ecrire xÉcrire la première valeur

48 Comment le faire en C #include void copier(int); /* prototype de la fopnction */ main(){ int n; cin >> n invcopier(n); } void invcopier(int n){ int x; if (n <= 0) return; /* Condition d'arrêt */ else{ cin >> x;/* Lire la première valeur */ invcopier(n-1);/* Copier les n-1 valeurs suivantes */ cout << x;/* Écrire la première valeur */ }

49 Trouver le maximum Description du problème: Lire un entiers n puis trouver le maximum des n entiers suivants lus en entrée. Entrée: Un entiers positif n suivit de n entiers séparés par un ou plusieurs caractères d'espacement. Sortie: Un entier représentant le maximum.

50 Exemple Sur l'entrée: 10 45 123 67 36 1 67 13 44 9 99 le programme doit afficher: 123

51 Fonction principale entier n maxi lire n maxi = maximum(n) écrire maxi où maximum satisfait le prototype entier maximum(entier)

52 Fonction maximum Entête: entier maximum(entier n) Corps: entier x y lire x y le maximum des n-1 valeurs suivantes retourner le maximum entre x et y

53 Fonction maximum Entête: entier maximum(entier n) Corps: entier x y lire x y maximum(n-1) retourner max(x,y) où max est une fonction satisfaisant le prototype suivant: entier max(entier, entier)

54 Fonction max Entête: entier max(entier a, entier b) Corps: si (a > b) alors retourner a sinon retourner b

55 Fonction maximum Entête: entier maximum(entier n) Corps: entier x y lire x si (n=1) alors retourner x(condition d'arrêt) sinon y maximum(n-1) retourner max(x,y) où max est une fonction satisfaisant le prototype suivant: entier max(entier, entier)

56 Comment le faire en C #include int maximum (int); /* prototype de la fopnction */ int max(int,int); main(){ int n, maxi; Cin >> n maxi = maximum(n) cout << maxi; } int maximum(int n){ int x, y; cin >> x; if (n=1) retunrn(x); /*(condition d'arrêt) */ else { y = maximum(n-1) return max(x,y); } } /* fin de la fonction */ int max(int x, int y){ if (x > y) return(x); else return(y); }

57 Le PGCD de deux nombres Description du problème: Calculer le plus grand commun diviseur entre deux entiers. Entrée: Deux entiers x et y Sortie: Un entier représentant le pgcd entre x et y

58 En reprenant lalgorithme quon a vu précédemment, la stratégie suvie est comme suit (on suppose que x > y): Si y divise x alors x est le PGCD de x et y Sinon, le pgcd de ces deux nombres est le même que celui de y et de x modulo y. Autrement dit, on peut définir le PGCD de x et Y comme suit:

59 PGCD(x,y) = y si s mod y = 0 PGCD(x,y) = PGCD(y, x modulo y) sinon. A partir de cette définition, on obtient la fonction suivante: entier PGCD (entier x, entier y) entier tmp; si x % y = 0 tmp = y; conditon darrêt sinon tmp = PGCD(y,x % y); retourner (tmp);

60 En C, on obtient: #include int PGCD (int,int); /* prototype de la fonction */ main(){ int x,y; cin >> x>>y; cout << PGCD(x,y); } int PGCD(int x, int y){ int tmp; if (x % y == 0) tmp = y; conditon darrêt else tmp = PGCD(y,x % y); return (tmp); } /* fin de la fonction */

61 Les tours de Hanoï

62 Description du problème: Montrez comment déplacer n disques de tailles distinctes d'une tige A vers une tige B en utilisant comme tampon une tige C. Initialement seule la tige A contient les n disques ordonnés avec le plus petit sur le dessus. On ne doit déplacer qu'un seul disque à la fois. Il est interdit de placer un disque sur un autre plus petit. Entrée: Un entier n représentant le nombre de disques. Sortie: Une série d'instructions de la forme " déplacer i vers j" indiquant les déplacements nécessaires pour résoudre le problème.

63 Fonction principale entier n lire n hanoi(n,1,2,3) où hanoi satisfait le prototype hanoi(entier, entier, entier, entier)

64 Supposons quon sache comment déplacer les (n-1) derniers disques de la tour 1 vers la tour 2, en utilisant la tour 3. déplacer le disque restant de la tour 1 vers la tour 2 déplacer maintenant les (n-1) disques de la tour 3 vers la tour 2, en saidant de la tour 1.

65 Fonction hanoi Entête: hanoi(entier n, entier i, entier j, entier k) (Affiche les instructions pour déplacer n disques de la tige i vers la tige k) Corps: si (n > 0) { hanoi(n-1, i, k, j) écrire "Déplacer i vers k); hanoi(n-1, j, i, k) }

66 En C on obtient: #include void hanoi (int,int,int,int) } /* fin de la fonction */ main(){ int n; cin>>n; hanoi(n,1,2,3); } void hanoi(int n,int i,int j,int k) { if (n>0) { hanoi(n-1,i,k,j); cout <<déplacer le disque de haut de la tour<<i<< à la tour <<k; hanoi(n-1,j,k,i); }

67 Exemple avec n = 4 disques: On obtient la série daffichages suivants: Déplacer le disque de haut de la tour 1 à la tour 2 Déplacer le disque de haut de la tour 1 à la tour 3 Déplacer le disque de haut de la tour 2 à la tour 3 Déplacer le disque de haut de la tour 1 à la tour 2 Déplacer le disque de haut de la tour 3 à la tour 1 Déplacer le disque de haut de la tour 3 à la tour 2 Déplacer le disque de haut de la tour 1 à la tour 2 Déplacer le disque de haut de la tour 1 à la tour 3 Déplacer le disque de haut de la tour 2 à la tour 3 Déplacer le disque de haut de la tour 2 à la tour 1 Déplacer le disque de haut de la tour 3 à la tour 1 Déplacer le disque de haut de la tour 2 à la tour 3 Déplacer le disque de haut de la tour 1 à la tour 2 Déplacer le disque de haut de la tour 1 à la tour 3 Déplacer le disque de haut de la tour 2 à la tour 3

68 Résumé Les composantes d'une fonction récursive si (condition d'arrêt) alors instructions sans appel récursif sinon instructions pouvant contenir un ou plusieurs appels récursifs (au moins un des paramètres d'appel est "décrémenté ou incrémenté dans le but de se diriger vers la condition darrêt " ).


Télécharger ppt "1 La récursion. Nous avons vu qu'un programme est constitué d'un ensemble de fonctions. Il est possible pour une fonction donnée d'appeler une autre fonction."

Présentations similaires


Annonces Google