Correction : principes de la récursivité

La fonction mystère


def f(a, n):
	if n == 0:
		return 0 
	return a + f(a, n-1)
			

Cas de base : lignes 3 et 4

Cas général : ligne 5

La fonction prend 2 paramètres, a et n. Le premier n'est jamais modifié, le deuxième diminue de 1 à chaque appel récursif.

→ exemple pour a = 2 et n = 3 :

Tracé fonction mystère

→ la fonction fait donc le produit de a par n.

Fonction puissance

Version itérative


def puissance(y:int, x: int)->int:
	p = 1
	for i in range(x):
		p = p * y
	return p
			

Version récursive

Cas général

Prenons l'exemple de x = 4 ( et y n'importe quelle valeur ) :

Donc : yx = y * yx-1, soit : puissance(y, x) = y * puissance(y, x - 1)

Cas de base

On arrête la récursion quand x == 0, et on renvoie alors 1.

(Remarque : pour "économiser" un appel récursif, on peut aussi prendre comme cas de base : quand x == 1, renvoyer y...)

Fonction complète


def puis_recurs(y: int, x: int)->int:
	if x == 0 : 
		return 1
	else:
		return y * puis_recurs(y, x-1)
			

Construire une chaîne

Cas général

Prenons par exemple i = 1 et n = 5 : la chaîne renvoyée par la fonction devra donc être "12345"

On en déduit donc que pour toute valeur de i : chaine(i, n) = i + chaine(i+1, n)

Cas de base

Quand i == n, on renvoie le dernier nombre à concaténer, à savoir n ( ou i, ils sont alors égaux 😏 )

Fonction complète


def chaine(i: int, n: int)->str:
	if i == n:
		return str(i)  # attention au transtypage indispensable int -> str !
	else:
		return str(i) + chaine(i+1, n)	
			

Caractère dans une chaîne

Cas général :

Ici, il faut voir que l'on va se contenter de "parcourir" la chaîne caractère après caractère depuis le premier : pour cela, on appelle la fonction en lui passant comme paramètre à chaque appel récursif, la chaîne, le caractère à rechercher et un troisième paramètre servant de "pointeur d'index" qui sera incrémenté à chaque appel récursif ( ceci jouant donc le rôle d'une itération du type : for caractere in chaine ).

Cas de base :

Il y en a en fait deux ici :

→ fonction complète :

	
def est_dans(ch: str, car: str, n = 0)->bool: # n = index du caractère "en cours", initialisé à 0 par défaut
    if n == len(ch): # cas de base : on est arrivé en bout de chaîne -> caractère pas trouvé
        return False
    if ch[n] == car: # cas de base : caractère d'indice n dans la chaîne == caractère recherché -> caractère trouvé
        return True
    else:
        return est_dans(ch ,car, n+1) # appel récursif en incrémentant n de 1 à chaque appel
        

Vous seriez peut-être tentés d'écrire à la dernière ligne :

	
........
    else:
        est_dans(ch ,car, n+1) # appel récursif en incrémentant n de 1 à chaque appel
        		

Qu'est-ce que cela renvoie ? Comment expliquez-vous ça ?? Faites la trace des appels récursifs et des résultats renvoyés...