Djamal Rebaïne1 1 La récursivité Une procédure est dite récursive si, et seulement si, elle...

47
Djamal Rebaïne 1 Djamal Rebaïne 1 La récursivité Une procédure est dite récursive si, et seulement si, elle fait appel à elle-même, soit directement soit indirectement

Transcript of Djamal Rebaïne1 1 La récursivité Une procédure est dite récursive si, et seulement si, elle...

Page 1: Djamal Rebaïne1 1 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 1

Djamal Rebaïne 1

La récursivité

Une procédure est dite récursive si, et seulement si, elle fait appel à elle-même, soit directement soit indirectement

Page 2: Djamal Rebaïne1 1 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 2

Page 3: Djamal Rebaïne1 1 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 3

- (vision itérative) Un escalier de hauteur h c’est :une séquence de h marches- (vision récursive) Un escalier de hauteur h c’est :une marche suivie d’un escalier de hauteur h − 1

Un exemple

Page 4: Djamal Rebaïne1 1 La récursivité Une procédure est dite récursive si, et seulement si, elle fait appel à elle-même, soit directement soit indirectement.

Version itérative :

static void monter_escalier( int h )

{

for (int i = 1; i <= h; i++)

monter_marche();

}

Version récursive :

void monter_escalier( int h )

{

if (h > 0)

monter_marche();

monter_escalier( h-1 );

}

Djamal Rebaïne 4

Page 5: Djamal Rebaïne1 1 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 5

Récursivité en action

• Que fait l’appel monter escalier( 3 ) ? monter_escalier( 3 ) = monter_marche(); monter_escalier( 2 ); = monter_marche(); monter_marche(); monter_escalier( 1 ); = monter_marche(); monter_marche(); monter_marche();

• Même effet que la version itérative, c’est-à-dire 3appels à monter marche()

Page 6: Djamal Rebaïne1 1 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ïne6

Recette de récursivité

• S’assurer que le problème peut se décomposer en unou plusieurs sous-problèmes de même nature

• Identifier le cas de base qui est le plus petit problèmequi ne se décompose pas en sous-problèmes

• Résoudre(P) = • si P est un cas de base, le résoudre directement • sinon • décomposer P en sous-problèmes P1, P2,... • résoudre récursivement P1, P2,... • combiner les résultats obtenus pour P1, P2, …, pour obtenir la solution pour avoir la solution au problème de départ.

Page 7: Djamal Rebaïne1 1 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 7

Fonctionnement d’une fonctionrécursive

• Création d’une pile pour la sauvegarde entre autres des paramètres d’appels de la procédure et la l’adresse de retour.

Page 8: Djamal Rebaïne1 1 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 8

Calculer le factoriel de n, noté n!

• Le problème est: Calculer le factoriel d'un nombre entier donné en entrée.

• En entrée: Nous avons n nombre entiers qui sont plus grands ou égaux à 0.

• Sortie: Nous avons un nombre entier qui représente le factoriel de n.

Page 9: Djamal Rebaïne1 1 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 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)

Page 10: Djamal Rebaïne1 1 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 10

Fonction factoriel

int factoriel(entier n) {

si (n < 1) retourner 1retourner n * factoriel(n-1)

}

Page 11: Djamal Rebaïne1 1 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 11

Comment le faire en assembleur?

On a besoin d’une pile!• En effet, à chaque appel récursif, la valeur du paramètre

n est sauvegardée dans la pile de travail. • Ce processus d’empilement est répété jusqu’à ce que le

paramètre actuel (de l’appel) n atteigne la valeur 0. Cela correspond à la fin de l’exécution de la fonction appelante.

• Ensuite, commence le dépilement, et l’exécution de la prochaine instruction de la fonction appelante est entamée. Ce processus de dépilement est répété jusqu’à ce qu’on atteigne la valeur de départ du paramètre n.

Page 12: Djamal Rebaïne1 1 La récursivité Une procédure est dite récursive si, et seulement si, elle fait appel à elle-même, soit directement soit indirectement.

12Djamal Rebaine

Cela se traduit par le programme assembleur suivant

TITLE factoriel PILE segment stack dw 100 dup(?) Basdepile equ this wordPILE endsData segment N dw 4 fact dw ?Data endsCode segment assume CS:code, DS:Data, SS:Pile Debut: MOV AX,Data MOV DS,AX MOV AX,Pile MOV SS, AX ; initialise le segment de pile MOV SP, basdepile ; copier l'adresse de la base de la pile dans SP mov BX,n; sauvegarde la valeur de n mov AX,BX Push AX call factoriel Fin: pop AX; le résultat calculé par la fonction factoriel est dans AX mov fact, AX mov AX,4c00h int 21h

Page 13: Djamal Rebaïne1 1 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 13

Factoriel proc near ; en utilisant la pile CMP AX,0 JA DEPILE MOV AX,1 JMP fin

DEPILE: ; dépiler jusqu’à ce n = 0 DEC AX PUSH AX ; factoriel(n-1) CALL FACTORIAL

RetourResultat: POP BX MUL BX fin: ret factoriel endp ; fin de la procédurecode ends end debut ; fin du programme code

Page 14: Djamal Rebaïne1 1 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 14Djamal Rebaïne 14

Calcul d’une somme par récursivité

Title sommerecursive; pour totaliser la somme de 1 jusqu’à n.PILE segment stack dw 100 dup(?) Basdepile equ this wordPILE endsData segment N dw 12 som dw ?Data endsCode segment assume CS:code, DS:Data, SS:Pile Debut: MOV AX,Data MOV DS,AX MOV AX,Pile MOV SS, AX ; initialise le segment de pile MOV SP, basdepile ; copier l'adresse de la base de la pile dans SP

Page 15: Djamal Rebaïne1 1 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 15

mov CX,n; sauvegarde la valeur de n XOR AX,AX CALL sommerecursive Fin: pop AX; le résultat calculé par la fonction factoriel est dans

AX mov fact, AX mov AX,4c00h int 21h

Page 16: Djamal Rebaïne1 1 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 16

sommerecursive proc near ;

CMP CX,0

JNZ fin

mov cx, 0

Fin: push cx

dec cx

CALL sommerecursive; resultat est dans cx

pop ax

add ax,cx

fin: ret

factoriel endp ; fin de la procédure

code ends

end debut ; fin du programme code

Page 17: Djamal Rebaïne1 1 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 17

Inversion d’une chaine de caractères

• Donnée: S une chaine de caractères

• Question: Afficher S dans le sens inverse

Page 18: Djamal Rebaïne1 1 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 18

• Fonction principale

• ecrire “introdroduire la chaîne: ”

• inverser

Page 19: Djamal Rebaïne1 1 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 19

Fonction factoriel

Entête:entier factoriel(entier n)

Corps:lire car;

si car <> `.` inverser; afficher car;

Page 20: Djamal Rebaïne1 1 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 20

La fonction inverser fonctionne comme suit:

Tant que le caractère lu n’est pas le point,

continuer la lecture;

Arrivé au point, l’affichage commence.

Page 21: Djamal Rebaïne1 1 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 21

TITLE INVERSER-CHAINE

affiche macro chaine ; mov dx,offset chaine ; mov ah, 09h ; int 21hendm PILE segment stack dw 100 dup(?) Basdepile equ this wordPILE endsData segmentChaine db ‘introduire votre chaine’, 10,13, ‘$’Data endsCode segment assume CS:code, DS:Data, SS:PileDebut: MOV AX,Data MOV DS,AX MOV AX,Pile MOV SS, AX ; initialise le segment de pile MOV SP, basdepile ; copier l'adresse de la base de la pile dans SP Affich chaine call inverser; APPEL DE LA FONCTION INVERSERFin: mov AX,4c00h int 21h

Page 22: Djamal Rebaïne1 1 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 22

inverser Proc near; les appels récursifs sont gérés exclusivement par la pile.

mov ah,1 ; lecture d’un caractère int 21hCMP AL,’.’ JNE dépiler; dépiler jusqu’à ce AL = ‘.’ CBW ; convertir le caractère en un mot

; ou alors faire mov AH,0 push AX

inverser

Depiler: POP AX mov AH,2 int 21 ret inverser; fin de la procédure

code ends; fin du programme principal end debut

Page 23: Djamal Rebaïne1 1 La récursivité Une procédure est dite récursive si, et seulement si, elle fait appel à elle-même, soit directement soit indirectement.

inverser Proc near; dans cette version, les appels récursifs sont gérés ; exclusivement par la pile. Continuer: mov ah,1 ; lecture d’un caractère int 21h CMP AL,’.’ JNE dépiler ; dépiler jusqu’à ce AL = ‘.’ CBW ; convertir le caractère en un mot ; ou alors faire mov AH,0 push AX JMP continuer

Depiler: POP AX mov AH,2 int 21 JMP depilerret inverser; fin de la procédure

code ends; fin du programme principal end debut

Djamal Rebaïne 23

Page 24: Djamal Rebaïne1 1 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 24

• Rechercher l’élément C dans un tableau trié dans l’ordre croissant.

…………… …..

milieuL u

AC?

Page 25: Djamal Rebaïne1 1 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 25

• Int void recherche(C,L,u:entier; trouve:booleen) • { • si (u <= L) • { milieu = (u - L + 1) div 2;• si A[milieu] = C • return (milieu);• sinon si A[milieu] > C • recherche(C,L,milieu-1);• sinon recherche(C,milieu+1,u);• } • sinon return (-1);• }

Page 26: Djamal Rebaïne1 1 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 26

TITLE dichotomique

PILE segment stack dw 100 dup(?) Basdepile equ this wordPILE endsData segmenttableau db 1, 4, 8, 10, 18Donnee db 18Data endsCode segment assume CS:code, DS:Data, SS:PileDebut: MOV AX,Data MOV DS,AX MOV AX,Pile MOV SS, AX ; initialise le segment de pile MOV SP, basdepile ; copier l'adresse de la base de la pile dans SP Lea SI, tableau; mov BX, SI Add BX, tableau[1] ; adresse du dernier élément du tableau push BX push SI call dichotoFin: mov AX,4c00h int 21h

Page 27: Djamal Rebaïne1 1 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 27

Dichoto proc near; pop SI pop BX CMP SI,BX JL fin ; continuer jusqu’à il n’y ait plus d’élément à rechercher

mov AX, BX ADD AX, SI Sub AX, 1 Mov DL,2 DIV DL CBW Mov CX,SI Mov SI, AX CMP [SI], donnee

jne appel mov AX,[SI] ret Appel: jg autreappel push BX push SI dichoto jmp finAutreappel: push SI push BX dichotoFin: ret code ends end debut

Page 28: Djamal Rebaïne1 1 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 28

Les nombres de Fibonacci

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

1;0

1 n si ;

10

21

FF

FFF nnn

èmen

Page 29: Djamal Rebaïne1 1 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 29

TITLE fibonacciSPILE SEGMENT STACK DW 100 DUP(?)SPILE ENDSSDATA SEGMENT n dw 6SDATA ENDSSCODE SEGMENT ASSUME CS:SCODE,DS:SDATA DEBUT: mov ax,sdata mov ds,ax xor ax,ax xor bx,bx mov ax,n call fibo mov dl,al add dl,30h mov ah,2 int 21hsortie: MOV AX,4C00H INT 21H

Page 30: Djamal Rebaïne1 1 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 30

Fibo proc si1: cmp ax, 1 ; comparer ax avec 1 ja else ; si n<= 1, retourner 1 mov ax, 1 ; mettre 1 dans ax retelse: dec ax ; décrémenter ax de 1 c'est-à-dire égal à n-1 push ax ; mettre n-1 sur la pile call Fibo ; résultat dans ax pop bx ; rectifier la pile et bx = n-1 dec bx ; bx = n -2 push ax ; sauvegarder ax = Fibonacci(n-1) sur la pile mov ax,bx ; passe le n-1 à ax pour exécuter Fibonacci(n-2) call Fibo ; résultat dans ax = Fibonacci(n-2) pop bx ; bx = Fibonacci(n-1) add ax, bx ; ax = Fibonacci(n-2) + Fibonacci(n-1) retFibo endpSCODE ENDS END DEBUT

Page 31: Djamal Rebaïne1 1 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 31

Les tours de Hanoï

http://www.multimania.com/fmaire/jeux/hanoi/hanoi.html

http://members.aa.net/~wgf/Hanoi/Hanoi.html

Page 32: Djamal Rebaïne1 1 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 32

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

Page 33: Djamal Rebaïne1 1 La récursivité Une procédure est dite récursive si, et seulement si, elle fait appel à elle-même, soit directement soit indirectement.

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

Djamal Rebaïne 33

Page 34: Djamal Rebaïne1 1 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 34

• Fonction principale

• entier n• lire n• hanoi(n,1,2,3)

• où hanoi satisfait le prototype

• hanoi(entier, entier, entier, entier)

Page 35: Djamal Rebaïne1 1 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 35

• Supposons qu’on 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 s’aidant de la tour 1.

Page 36: Djamal Rebaïne1 1 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 36

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)

}

Page 37: Djamal Rebaïne1 1 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 37

• #include <iostream.h>

• void hanoi (int,int,int,int)

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

• }

• main()

• {

• int n;

• cin>>n;

• hanoi(n,1,2,3);

• }

Page 38: Djamal Rebaïne1 1 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 38

Exemple avec n = 4 disques

• On obtient la série d’affichages 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

Page 39: Djamal Rebaïne1 1 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 39

Voyons cela de plus près

Page 40: Djamal Rebaïne1 1 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 40

Pas-à-pas avec n=3

entier n nfactlire n si (n < 0) alors écrire “entrée négative: ” nsinon hanoi(n,1,2,3);

entier n

.

.

.

.

.

.

n

Page 41: Djamal Rebaïne1 1 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 41

entier nlire n nfactsi (n < 0) alors écrire “entrée négative: ” nsinon hanoi(n,1,2,3)

lire n

.

.

.

.

.

.

3n

Page 42: Djamal Rebaïne1 1 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 42

entier n lire nsi (n < 0) alors écrire “entrée négative: ” nsinon hanoi(n,1,2,3)

.

.

.

.

.

.

4n entier

Page 43: Djamal Rebaïne1 1 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 43

entier n nfactlire nsi (n < 0) alors écrire “entrée négative: ” nsinon hanoi(3,1,2,3)

1

.

.

.

.

.

.

3

2

3

3

n entier

entiern

entier

si (n 0) retourner hanoi(2,3,2,1)hanoi( , , , )

Page 44: Djamal Rebaïne1 1 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 44

TITLE hanoi-program

SPILE SEGMENT STACK

DW 100 DUP(?)

SPILE ENDS

SDATA SEGMENT

n dw 6

SDATA ENDS

SCODE SEGMENT

ASSUME CS:SCODE,DS:SDATA

DEBUT:

mov ax,sdata

mov ds,ax

xor ax,ax

xor cx,cx

xor dx,dx

xor bx,bx

mov ax,n

mov cl,1; la tour i

mov ch,2; la tour j

mov dh,3; la tour k

call hanoi

sortie:

MOV AX,4C00H

INT 21H

Page 45: Djamal Rebaïne1 1 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 45

hanoi proc near

si1:

cmp ax, 0 ; comparer ax avec 0

ja else ; si n> 0, continuer

ret

else:

dec ax ; décrémenter ax de 1 c'est-à-dire égal à n-1

mov temp, ch

mov ch, dh

mov dh, temp

push cl ; sauvegarder en premier le i

push dh ; sauvegarder en deuxième le k

push ch ; sauvegarder en troisième le j

push ax ; mettre n -1 sur la pile

call hanoi ; appel à hanoi

Page 46: Djamal Rebaïne1 1 La récursivité Une procédure est dite récursive si, et seulement si, elle fait appel à elle-même, soit directement soit indirectement.

; passer au déplacement des tours

mov al, cl ; mettre le i dans al

mov ah,2

int 21h

mov al, 32 ; mettre un blanc dans al

mov ah,2

int 21h

mov al, dl ; mettre le k dans al

mov ah,2

int 21h

Djamal Rebaïne 46

Page 47: Djamal Rebaïne1 1 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 47

pop ax ; ax = n-1

pop dh

pop ch

pop cl

push ch

push cl

push dh

call hanoi

ret

Hanoi endp

SCODE ENDS

END DEBUT