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.

Slides:



Advertisements
Présentations similaires
La boucle for : init7.c et init71.c
Advertisements

Cours de C – Séance dexercices 25 Septembre 2007.
Chapitre annexe. Récursivité
Les fonctions A quoi ça sert ?
A RECUPERER EN ENTRANT Le polycopié de Caml Partie 1
Rappels C.
Calculs de complexité d'algorithmes
CHAPITRE 2 Nombres entiers, initiation à l’arithmétique- Nombres rationnels.
5. Les structures répétitives
Les sous-programmes Chapitre n° 5: Objectifs : Activité:
Nous allons vous présenter: - Photoshop - Algorithme et programmation
Langage C Révision.
Références Bibliographiques
ALGORITHMES RECURSIFS
Introduction à la programmation (420-PK2-SL) cours 12 Gestion des applications Technologie de linformation (LEA.BW)
Récursivité.
Algorithmique et Programmation
8PRO100 Éléments de programmation Comment faire prendre une décision à un ordinateur?
Correction du reste des exercices
PGCD : sous ce sigle un peu bizarre se cache un outil bien utile dans les simplifications de fractions, mais aussi dans bien des problèmes de la vie courante…
La récursivité Une procédure est dite récursive si, et seulement si, elle fait appel à elle-même, soit directement soit indirectement Djamal Rebaïne Djamal.
Introduction à la récursivité
Sémantique axiomatique
Programme de baccalauréat en informatique Algorithmique et programmation IFT-1001 Thierry EUDE Hatem Mahbouli Laboratoire #12 Département dinformatique.
Nombres entiers. Ensembles de nombres
TRAITEMENT DE STRUCTURES
Particularités des calculs
Chapitre 1 PGCD de deux nombres.
ARITHMETIQUE : NOMBRES PREMIERS, PGCD
Leçon 2 : Surcharge des opérateurs IUP 2 Génie Informatique Méthode et Outils pour la Programmation Françoise Greffier Université de Franche-Comté.
Bases de la programmation en C++ 1 Les enchaînementsdinstruction Séquentiels. Exécutions dinstructions les unes à la suite des autres. Instructions séparées.
Récursivité Définition récursive d’un problème. Critère d’arrêt et convergence. Performance des algorithmes récursifs. Résolution d’un problème à l’aide.
Abder Alikacem Semaine 13 La récursivité
Introduction à l’algorithmique
Points importants de la semaine Le préprocesseur. La conversion de types. Les fonctions.
1 PROTOTYPE PGC++ Vecteur_3D DÉFINITION. 2 class Vecteur_3D { private : float vx, vy, vz, vw; // Représentation en coordonnées homogènes. public : Vecteur_3D();
STRUCTURES DE DONNÉES Maxime CROCHEMORE
IFT 6800 Atelier en Technologies d’information
8PRO107 Éléments de programmation
8PRO107 Éléments de programmation
Programme de baccalauréat en informatique Programmation Orientée Objets IFT Thierry EUDE Module 6. Gestion des erreurs et des exceptions : Fonctionnement.
Structures de données IFT-2000 Abder Alikacem La récursivité Semaine 5 Département dinformatique et de génie logiciel Édition Septembre 2009.
Programmation linéaire en nombres entiers : les méthodes de troncature
Formation C++. Hello World ! #include /* Commentaire sur plusieurs lignes */ int main() { //Affiche hello world std::cout
La librairie assert.h.
Le langage C Structures de données
SPIP SPIP est le système de publication développé par le minirézo.
Le chiffrement asymétrique
Sous-programmes.
INTRODUCTION.
Les adresses des fonctions
8PRO100 Éléments de programmation Comment répéter plusieurs fois une séquence d’instructions.
Argc et argv Utilisation des paramètres de la ligne de commande.
Un survol du language C.
Arbres binaires et tables de hachage
1 Sixième journée Éléments de C++ La programmation typée Éléments de C++ La programmation typée.
TABLEAUX des POINTEURS TRAITEMENT DE STRUCTURES
Conception de Programmes - IUT de Paris - 1ère année – Cours 8 – Les entrées/sorties Comment fonctionnent les opérateurs > pour les types élémentaires.
Les algorithmes recursifs
Introduction à la récursivité
Introduction au langage C : Structures de contrôle 1 ère année Génie Informatique Dr Daouda Traoré Université de Ségou
6ième Classe (Mercredi, 17 novembre) CSI2572
2005/2006 Structures de Données Introduction à la complexité des algorithmes.
La récursivité Mireille Goud HEG Vd AlgSD - Résurisivité.
CPI/BTS 2 Algorithmique & Programmation La récursivité Algo – Prog CPI/BTS2 – M. Dravet – 14/09/2003 Dernière modification: 14/09/2003.
Introduction à la programmation (420-PK2-SL) cours 13 Gestion des applications Technologie de l’information (LEA.BW)
8PRO107 Éléments de programmation Les tableaux. Étude de cas 1 Description du problème : Lire une liste d’entiers et l’afficher d’abord dans le même ordre.
La récursivité.
Structures de données IFT-2000 Abder Alikacem La récursivité Semaine 5 Département d’informatique et de génie logiciel Édition Septembre 2009.
M. BENJELLOUN : 2005 Le but final est de programmer un jeu où l'ordinateur choisira un nombre aléatoire entre 0 et 100 que vous devez deviner.
Transcription de la présentation:

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. Que se passe-t-il si une fonction s'appelle elle- même? C'est ce que l'on appelle la récursion.

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

#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.

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

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

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.

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)

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)

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

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

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

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 n nfact

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 n nfact entier

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) n nfact entier

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 n nfact entier n 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 n nfact n si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 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 n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1)

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 n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) n entier

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 n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 1 nentier

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 n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) n entier

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 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) 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 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) 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 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)

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 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

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 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

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 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

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 n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) n entier retourner n * 2

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 n nfact n si (n 1) retourner 1 retourner n * factoriel(n-1) retourner n * 6

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 n nfact entier nfact 24

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 n nfact écrire la factorielle de n est nfact

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 n nfact entier est 24 La factorielle de 4 est 24

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

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.

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

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.

Exemple Sur l'entrée: le programme doit afficher:

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

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

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

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

#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

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.

Exemple Sur l'entrée: le programme doit afficher:

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

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

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

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 */ }

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.

Exemple Sur l'entrée: le programme doit afficher: 123

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

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

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)

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

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)

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); }

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

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:

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);

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 */

Les tours de Hanoï

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.

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

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.

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) }

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); }

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

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 " ).