Structures de donn´ ees et algorithmes fondamentaux
R´ecursivit´e sur des it´erables
Anthony Labarre
Universit´e Gustave Eiffel
18 novembre 2020
Rappels
I On a vu la fois pass´ee la notion d’algorithme r´ecursif ;
I On a vu qu’un tel algorithme n´ecessitait une condition d’arrˆet ; I Et on a aussi vu que la premi`ere ´etape consistait `a trouver une
formulation r´ecursive du probl`eme `a r´esoudre ;
I Pour obtenir des algorithmes r´ecursifs sur des it´erables, il est important de les repr´esenter aussi de mani`ere r´ecursive ;
Vision r´ ecursive des listes
I Pour concevoir des algorithmes r´ecursifs sur des listes, il faut changer de point de vue ;
I Dans le point de vue it´eratif, une liste est une s´equence d’´el´ements :
I Dans le point de vue r´ecursif, une liste est :
1. soit vide, soit form´ee d’une liste suivie d’un ´el´ement ;
+
2. soit vide, soit form´ee d’un ´el´ement suivi d’une liste ;
+
I Le “bon” d´ecoupage d´epend du probl`eme `a r´esoudre ; I On pourra ainsi appliquer la m´ethodologie de la fois pass´ee ;
3
Vision r´ ecursive des listes
I Pour concevoir des algorithmes r´ecursifs sur des listes, il faut changer de point de vue ;
I Dans le point de vue it´eratif, une liste est une s´equence d’´el´ements :
I Dans le point de vue r´ecursif, une liste est :
1. soit vide, soit form´ee d’une liste suivie d’un ´el´ement ;
+
2. soit vide, soit form´ee d’un ´el´ement suivi d’une liste ;
+
I Le “bon” d´ecoupage d´epend du probl`eme `a r´esoudre ; I On pourra ainsi appliquer la m´ethodologie de la fois pass´ee ;
Vision r´ ecursive des listes
I Pour concevoir des algorithmes r´ecursifs sur des listes, il faut changer de point de vue ;
I Dans le point de vue it´eratif, une liste est une s´equence d’´el´ements :
I Dans le point de vue r´ecursif, une liste est :
1. soit vide, soit form´ee d’une liste suivie d’un ´el´ement ;
+
2. soit vide, soit form´ee d’un ´el´ement suivi d’une liste ;
+
I Le “bon” d´ecoupage d´epend du probl`eme `a r´esoudre ; I On pourra ainsi appliquer la m´ethodologie de la fois pass´ee ;
5
Vision r´ ecursive des listes
I Pour concevoir des algorithmes r´ecursifs sur des listes, il faut changer de point de vue ;
I Dans le point de vue it´eratif, une liste est une s´equence d’´el´ements :
I Dans le point de vue r´ecursif, une liste est :
1. soit vide, soit form´ee d’une liste suivie d’un ´el´ement ;
+
2. soit vide, soit form´ee d’un ´el´ement suivi d’une liste ;
+
I Le “bon” d´ecoupage d´epend du probl`eme `a r´esoudre ; I On pourra ainsi appliquer la m´ethodologie de la fois pass´ee ;
Vision r´ ecursive des listes
I Pour concevoir des algorithmes r´ecursifs sur des listes, il faut changer de point de vue ;
I Dans le point de vue it´eratif, une liste est une s´equence d’´el´ements :
I Dans le point de vue r´ecursif, une liste est :
1. soit vide, soit form´ee d’une liste suivie d’un ´el´ement ;
+
2. soit vide, soit form´ee d’un ´el´ement suivi d’une liste ;
+
I Le “bon” d´ecoupage d´epend du probl`eme `a r´esoudre ; I On pourra ainsi appliquer la m´ethodologie de la fois pass´ee ;
7
Vision r´ ecursive des listes
I Pour concevoir des algorithmes r´ecursifs sur des listes, il faut changer de point de vue ;
I Dans le point de vue it´eratif, une liste est une s´equence d’´el´ements :
I Dans le point de vue r´ecursif, une liste est :
1. soit vide, soit form´ee d’une liste suivie d’un ´el´ement ;
+
2. soit vide, soit form´ee d’un ´el´ement suivi d’une liste ;
+
I Le “bon” d´ecoupage d´epend du probl`eme `a r´esoudre ; I On pourra ainsi appliquer la m´ethodologie de la fois pass´ee ;
Vision r´ ecursive des listes
I Pour concevoir des algorithmes r´ecursifs sur des listes, il faut changer de point de vue ;
I Dans le point de vue it´eratif, une liste est une s´equence d’´el´ements :
I Dans le point de vue r´ecursif, une liste est :
1. soit vide, soit form´ee d’une liste suivie d’un ´el´ement ;
+
2. soit vide, soit form´ee d’un ´el´ement suivi d’une liste ;
+
I Le “bon” d´ecoupage d´epend du probl`eme `a r´esoudre ; I On pourra ainsi appliquer la m´ethodologie de la fois pass´ee ;
9
Vision r´ ecursive des listes
I Pour concevoir des algorithmes r´ecursifs sur des listes, il faut changer de point de vue ;
I Dans le point de vue it´eratif, une liste est une s´equence d’´el´ements :
I Dans le point de vue r´ecursif, une liste est :
1. soit vide, soit form´ee d’une liste suivie d’un ´el´ement ;
+
2. soit vide, soit form´ee d’un ´el´ement suivi d’une liste ;
+
I Le “bon” d´ecoupage d´epend du probl`eme `a r´esoudre ;
I On pourra ainsi appliquer la m´ethodologie de la fois pass´ee ;
Vision r´ ecursive des listes
I Pour concevoir des algorithmes r´ecursifs sur des listes, il faut changer de point de vue ;
I Dans le point de vue it´eratif, une liste est une s´equence d’´el´ements :
I Dans le point de vue r´ecursif, une liste est :
1. soit vide, soit form´ee d’une liste suivie d’un ´el´ement ;
+
2. soit vide, soit form´ee d’un ´el´ement suivi d’une liste ;
+
I Le “bon” d´ecoupage d´epend du probl`eme `a r´esoudre ; I On pourra ainsi appliquer la m´ethodologie de la fois pass´ee ;
11
Impacts des d´ ecoupages sur les appels r´ ecursifs
La structure des param`etres dans les appels r´ecursifs d´ependra du d´ecoupage utilis´e :
D´ecoupage 1
appel 1 :
appel 2 : appel 3 :
... appeln−2 : appeln−1 : appeln:
D´ecoupage 2
...
Impacts des d´ ecoupages sur les appels r´ ecursifs
La structure des param`etres dans les appels r´ecursifs d´ependra du d´ecoupage utilis´e :
D´ecoupage 1
appel 1 : appel 2 :
appel 3 : ... appeln−2 : appeln−1 : appeln:
D´ecoupage 2
...
13
Impacts des d´ ecoupages sur les appels r´ ecursifs
La structure des param`etres dans les appels r´ecursifs d´ependra du d´ecoupage utilis´e :
D´ecoupage 1
appel 1 : appel 2 : appel 3 :
... appeln−2 : appeln−1 : appeln:
D´ecoupage 2
...
Impacts des d´ ecoupages sur les appels r´ ecursifs
La structure des param`etres dans les appels r´ecursifs d´ependra du d´ecoupage utilis´e :
D´ecoupage 1
appel 1 : appel 2 : appel 3 :
...
appeln−2 : appeln−1 : appeln:
D´ecoupage 2
...
15
Impacts des d´ ecoupages sur les appels r´ ecursifs
La structure des param`etres dans les appels r´ecursifs d´ependra du d´ecoupage utilis´e :
D´ecoupage 1
appel 1 : appel 2 : appel 3 :
... appeln−2 :
appeln−1 : appeln:
D´ecoupage 2
...
Impacts des d´ ecoupages sur les appels r´ ecursifs
La structure des param`etres dans les appels r´ecursifs d´ependra du d´ecoupage utilis´e :
D´ecoupage 1
appel 1 : appel 2 : appel 3 :
... appeln−2 : appeln−1 :
appeln:
D´ecoupage 2
...
17
Impacts des d´ ecoupages sur les appels r´ ecursifs
La structure des param`etres dans les appels r´ecursifs d´ependra du d´ecoupage utilis´e :
D´ecoupage 1
appel 1 : appel 2 : appel 3 :
... appeln−2 : appeln−1 : appeln:
D´ecoupage 2
...
Exemple 1 : recherche r´ ecursive d’un ´ el´ ement
I R´eimpl´ementons de mani`ere r´ecursive la recherche lin´eaire ;
I On cherche un ´el´ementedans une liste L, et on veut renvoyer sa position si on le trouve (None sinon) ;
I Appliquons la m´ethodologie de la fois pass´ee :
1. trouver une formulation r´ecursive :selon le d´ecoupage choisi :
1.1 + : sien’est pas en derni`ere position, on doit le chercher dans la sous-liste qui pr´ec`ede ;
1.2 + : sien’est pas en premi`ere position, on doit le chercher dans la sous-liste qui suit ;
2. trouver une condition d’arrˆet :dans les deux cas :
I Lest vide⇒renvoyerNone;
I l’´el´ement isol´e este⇒renvoyer sa position ;
I On peut maintenant traduire ce raisonnement en code ... mais comment faire ?
19
Exemple 1 : recherche r´ ecursive d’un ´ el´ ement
I R´eimpl´ementons de mani`ere r´ecursive la recherche lin´eaire ; I On cherche un ´el´ementedans une liste L, et on veut renvoyer
sa position si on le trouve (None sinon) ;
I Appliquons la m´ethodologie de la fois pass´ee :
1. trouver une formulation r´ecursive :selon le d´ecoupage choisi :
1.1 + : sien’est pas en derni`ere position, on doit le chercher dans la sous-liste qui pr´ec`ede ;
1.2 + : sien’est pas en premi`ere position, on doit le chercher dans la sous-liste qui suit ;
2. trouver une condition d’arrˆet :dans les deux cas :
I Lest vide⇒renvoyerNone;
I l’´el´ement isol´e este⇒renvoyer sa position ;
I On peut maintenant traduire ce raisonnement en code ... mais comment faire ?
Exemple 1 : recherche r´ ecursive d’un ´ el´ ement
I R´eimpl´ementons de mani`ere r´ecursive la recherche lin´eaire ; I On cherche un ´el´ementedans une liste L, et on veut renvoyer
sa position si on le trouve (None sinon) ; I Appliquons la m´ethodologie de la fois pass´ee :
1. trouver une formulation r´ecursive :selon le d´ecoupage choisi :
1.1 + : sien’est pas en derni`ere position, on doit le chercher dans la sous-liste qui pr´ec`ede ;
1.2 + : sien’est pas en premi`ere position, on doit le chercher dans la sous-liste qui suit ;
2. trouver une condition d’arrˆet :dans les deux cas :
I Lest vide⇒renvoyerNone;
I l’´el´ement isol´e este⇒renvoyer sa position ;
I On peut maintenant traduire ce raisonnement en code ... mais comment faire ?
21
Exemple 1 : recherche r´ ecursive d’un ´ el´ ement
I R´eimpl´ementons de mani`ere r´ecursive la recherche lin´eaire ; I On cherche un ´el´ementedans une liste L, et on veut renvoyer
sa position si on le trouve (None sinon) ; I Appliquons la m´ethodologie de la fois pass´ee :
1. trouver une formulation r´ecursive :selon le d´ecoupage choisi :
1.1 + : sien’est pas en derni`ere position, on doit le chercher dans la sous-liste qui pr´ec`ede ;
1.2 + : sien’est pas en premi`ere position, on doit le chercher dans la sous-liste qui suit ;
2. trouver une condition d’arrˆet :dans les deux cas :
I Lest vide⇒renvoyerNone;
I l’´el´ement isol´e este⇒renvoyer sa position ;
I On peut maintenant traduire ce raisonnement en code ... mais comment faire ?
Exemple 1 : recherche r´ ecursive d’un ´ el´ ement
I R´eimpl´ementons de mani`ere r´ecursive la recherche lin´eaire ; I On cherche un ´el´ementedans une liste L, et on veut renvoyer
sa position si on le trouve (None sinon) ; I Appliquons la m´ethodologie de la fois pass´ee :
1. trouver une formulation r´ecursive :selon le d´ecoupage choisi :
1.1 + : sien’est pas en derni`ere position, on doit le chercher dans la sous-liste qui pr´ec`ede ;
1.2 + : sien’est pas en premi`ere position, on doit le chercher dans la sous-liste qui suit ;
2. trouver une condition d’arrˆet :dans les deux cas :
I Lest vide⇒renvoyerNone;
I l’´el´ement isol´e este⇒renvoyer sa position ;
I On peut maintenant traduire ce raisonnement en code ... mais comment faire ?
23
Exemple 1 : recherche r´ ecursive d’un ´ el´ ement
I R´eimpl´ementons de mani`ere r´ecursive la recherche lin´eaire ; I On cherche un ´el´ementedans une liste L, et on veut renvoyer
sa position si on le trouve (None sinon) ; I Appliquons la m´ethodologie de la fois pass´ee :
1. trouver une formulation r´ecursive :selon le d´ecoupage choisi :
1.1 + : sien’est pas en derni`ere position, on doit le chercher dans la sous-liste qui pr´ec`ede ;
1.2 + : sien’est pas en premi`ere position, on doit le chercher dans la sous-liste qui suit ;
2. trouver une condition d’arrˆet :dans les deux cas :
I Lest vide⇒renvoyerNone;
I l’´el´ement isol´e este⇒renvoyer sa position ;
I On peut maintenant traduire ce raisonnement en code ... mais comment faire ?
Exemple 1 : recherche r´ ecursive d’un ´ el´ ement
I R´eimpl´ementons de mani`ere r´ecursive la recherche lin´eaire ; I On cherche un ´el´ementedans une liste L, et on veut renvoyer
sa position si on le trouve (None sinon) ; I Appliquons la m´ethodologie de la fois pass´ee :
1. trouver une formulation r´ecursive :selon le d´ecoupage choisi :
1.1 + : sien’est pas en derni`ere position, on doit le chercher dans la sous-liste qui pr´ec`ede ;
1.2 + : sien’est pas en premi`ere position, on doit le chercher dans la sous-liste qui suit ;
2. trouver une condition d’arrˆet :dans les deux cas :
I Lest vide⇒renvoyerNone;
I l’´el´ement isol´e este⇒renvoyer sa position ;
I On peut maintenant traduire ce raisonnement en code ... mais comment faire ?
25
Exemple 1 : recherche r´ ecursive d’un ´ el´ ement
I R´eimpl´ementons de mani`ere r´ecursive la recherche lin´eaire ; I On cherche un ´el´ementedans une liste L, et on veut renvoyer
sa position si on le trouve (None sinon) ; I Appliquons la m´ethodologie de la fois pass´ee :
1. trouver une formulation r´ecursive :selon le d´ecoupage choisi :
1.1 + : sien’est pas en derni`ere position, on doit le chercher dans la sous-liste qui pr´ec`ede ;
1.2 + : sien’est pas en premi`ere position, on doit le chercher dans la sous-liste qui suit ;
2. trouver une condition d’arrˆet :dans les deux cas : I Lest vide⇒renvoyerNone;
I l’´el´ement isol´e este⇒renvoyer sa position ;
I On peut maintenant traduire ce raisonnement en code ... mais comment faire ?
Exemple 1 : recherche r´ ecursive d’un ´ el´ ement
I R´eimpl´ementons de mani`ere r´ecursive la recherche lin´eaire ; I On cherche un ´el´ementedans une liste L, et on veut renvoyer
sa position si on le trouve (None sinon) ; I Appliquons la m´ethodologie de la fois pass´ee :
1. trouver une formulation r´ecursive :selon le d´ecoupage choisi :
1.1 + : sien’est pas en derni`ere position, on doit le chercher dans la sous-liste qui pr´ec`ede ;
1.2 + : sien’est pas en premi`ere position, on doit le chercher dans la sous-liste qui suit ;
2. trouver une condition d’arrˆet :dans les deux cas : I Lest vide⇒renvoyerNone;
I l’´el´ement isol´e este⇒renvoyer sa position ;
I On peut maintenant traduire ce raisonnement en code ... mais comment faire ?
27
Exemple 1 : recherche r´ ecursive d’un ´ el´ ement
I R´eimpl´ementons de mani`ere r´ecursive la recherche lin´eaire ; I On cherche un ´el´ementedans une liste L, et on veut renvoyer
sa position si on le trouve (None sinon) ; I Appliquons la m´ethodologie de la fois pass´ee :
1. trouver une formulation r´ecursive :selon le d´ecoupage choisi :
1.1 + : sien’est pas en derni`ere position, on doit le chercher dans la sous-liste qui pr´ec`ede ;
1.2 + : sien’est pas en premi`ere position, on doit le chercher dans la sous-liste qui suit ;
2. trouver une condition d’arrˆet :dans les deux cas : I Lest vide⇒renvoyerNone;
I l’´el´ement isol´e est ⇒renvoyer sa position ;
Option 1 : r´ ecursivit´ e ` a l’aide de slices
I Le plus simple : utiliser des slices;
Exemple 1 (d´ecoupage 1 (liste + ´el´ement))
def recherche_recursive_slices(liste, element): if liste: # si L est vide, on abandonne
if element == liste[-1]: return len(liste) - 1
return recherche_recursive_slices(liste[:-1], element)
I Est-ce que ¸ca fonctionne ? Oui, mais :
I chaque appel r´ecursif cr´ee unslice, qui est unecopie d’un morceau de la liste de d´epart ;
I les copies prennent du temps et de la place en m´emoire :
n−1 +n−2 +. . .+ 1 =O(n2) ;
I . . . et donc la recherche elle-mˆeme a une complexit´e de O(n2) au lieu duO(n) dans la version it´erative ;
29
Option 1 : r´ ecursivit´ e ` a l’aide de slices
I Le plus simple : utiliser des slices;
Exemple 1 (d´ecoupage 1 (liste + ´el´ement))
def recherche_recursive_slices(liste, element):
if liste: # si L est vide, on abandonne if element == liste[-1]:
return len(liste) - 1
return recherche_recursive_slices(liste[:-1], element)
I Est-ce que ¸ca fonctionne ? Oui, mais :
I chaque appel r´ecursif cr´ee unslice, qui est unecopie d’un morceau de la liste de d´epart ;
I les copies prennent du temps et de la place en m´emoire :
n−1 +n−2 +. . .+ 1 =O(n2) ;
I . . . et donc la recherche elle-mˆeme a une complexit´e de O(n2) au lieu duO(n) dans la version it´erative ;
Option 1 : r´ ecursivit´ e ` a l’aide de slices
I Le plus simple : utiliser des slices;
Exemple 1 (d´ecoupage 1 (liste + ´el´ement))
def recherche_recursive_slices(liste, element):
if liste: # si L est vide, on abandonne if element == liste[-1]:
return len(liste) - 1
return recherche_recursive_slices(liste[:-1], element)
I Est-ce que ¸ca fonctionne ? Oui, mais :
I chaque appel r´ecursif cr´ee unslice, qui est unecopie d’un morceau de la liste de d´epart ;
I les copies prennent du temps et de la place en m´emoire :
n−1 +n−2 +. . .+ 1 =O(n2) ;
I . . . et donc la recherche elle-mˆeme a une complexit´e de O(n2) au lieu duO(n) dans la version it´erative ;
31
Option 1 : r´ ecursivit´ e ` a l’aide de slices
I Le plus simple : utiliser des slices;
Exemple 1 (d´ecoupage 1 (liste + ´el´ement))
def recherche_recursive_slices(liste, element):
if liste: # si L est vide, on abandonne if element == liste[-1]:
return len(liste) - 1
return recherche_recursive_slices(liste[:-1], element)
I Est-ce que ¸ca fonctionne ? Oui, mais :
I chaque appel r´ecursif cr´ee unslice, qui est unecopie d’un morceau de la liste de d´epart ;
I les copies prennent du temps et de la place en m´emoire :
n−1 +n−2 +. . .+ 1 =O(n2) ;
I . . . et donc la recherche elle-mˆeme a une complexit´e de O(n2) au lieu duO(n) dans la version it´erative ;
Option 1 : r´ ecursivit´ e ` a l’aide de slices
I Le plus simple : utiliser des slices;
Exemple 1 (d´ecoupage 1 (liste + ´el´ement))
def recherche_recursive_slices(liste, element):
if liste: # si L est vide, on abandonne if element == liste[-1]:
return len(liste) - 1
return recherche_recursive_slices(liste[:-1], element)
I Est-ce que ¸ca fonctionne ? Oui, mais :
I chaque appel r´ecursif cr´ee unslice, qui est unecopie d’un morceau de la liste de d´epart ;
I les copies prennent du temps et de la place en m´emoire :
n−1 +n−2 +. . .+ 1 =O(n2) ;
I . . . et donc la recherche elle-mˆeme a une complexit´e de O(n2) au lieu duO(n) dans la version it´erative ;
33
Option 1 : r´ ecursivit´ e ` a l’aide de slices
I Le plus simple : utiliser des slices;
Exemple 1 (d´ecoupage 1 (liste + ´el´ement))
def recherche_recursive_slices(liste, element):
if liste: # si L est vide, on abandonne if element == liste[-1]:
return len(liste) - 1
return recherche_recursive_slices(liste[:-1], element)
I Est-ce que ¸ca fonctionne ? Oui, mais :
I chaque appel r´ecursif cr´ee unslice, qui est unecopie d’un morceau de la liste de d´epart ;
I les copies prennent du temps et de la place en m´emoire :
n−1 +n−2 +. . .+ 1 =O(n2) ;
Option 2 : r´ ecursivit´ e ` a l’aide d’indices
I Solution plus intelligente : utiliser un indice pour progresser dans les sous-listes sans les cr´eer ;
Exemple 2 (d´ecoupage 1 (liste + ´el´ement))
def recherche_recursive(liste, element, position): if position < 0: # condition d'arr^et
return None
if liste[position] == element: return position
return recherche_recursive(liste, element, position - 1)
I Comme on ne veut pas demander `a l’utilisateur de fournir la position, on cr´ee une fonction auxiliaire :
Exemple 3 (d´ecoupage 1 (liste + ´el´ement))
def recherche_element(liste, element):
return recherche_recursive(liste, element, len(liste) - 1)
35
Option 2 : r´ ecursivit´ e ` a l’aide d’indices
I Solution plus intelligente : utiliser un indice pour progresser dans les sous-listes sans les cr´eer ;
Exemple 2 (d´ecoupage 1 (liste + ´el´ement))
def recherche_recursive(liste, element, position):
if position < 0: # condition d'arr^et return None
if liste[position] == element:
return position
return recherche_recursive(liste, element, position - 1)
I Comme on ne veut pas demander `a l’utilisateur de fournir la position, on cr´ee une fonction auxiliaire :
Exemple 3 (d´ecoupage 1 (liste + ´el´ement))
def recherche_element(liste, element):
return recherche_recursive(liste, element, len(liste) - 1)
Option 2 : r´ ecursivit´ e ` a l’aide d’indices
I Solution plus intelligente : utiliser un indice pour progresser dans les sous-listes sans les cr´eer ;
Exemple 2 (d´ecoupage 1 (liste + ´el´ement))
def recherche_recursive(liste, element, position):
if position < 0: # condition d'arr^et return None
if liste[position] == element:
return position
return recherche_recursive(liste, element, position - 1)
I Comme on ne veut pas demander `a l’utilisateur de fournir la position, on cr´ee une fonction auxiliaire :
Exemple 3 (d´ecoupage 1 (liste + ´el´ement))
def recherche_element(liste, element):
return recherche_recursive(liste, element, len(liste) - 1)
37
Option 2 : r´ ecursivit´ e ` a l’aide d’indices
I Solution plus intelligente : utiliser un indice pour progresser dans les sous-listes sans les cr´eer ;
Exemple 2 (d´ecoupage 1 (liste + ´el´ement))
def recherche_recursive(liste, element, position):
if position < 0: # condition d'arr^et return None
if liste[position] == element:
return position
return recherche_recursive(liste, element, position - 1)
I Comme on ne veut pas demander `a l’utilisateur de fournir la position, on cr´ee une fonction auxiliaire :
Avantages des indices
I Plus besoin des slices, donc :
I consommation en m´emoire plus raisonnable (O(n2)⇒O(n)) ; I calculs plus rapides (O(n2)⇒O(n)) ;
I Plus portable : les slicessont propres `a Python, les indices sont utilisables dans tous les langages ;
39
Cas plus complexes
I Jusqu’ici, les algorithmes r´ecursifs qu’on a vus n’´etaient pas indispensables :
I on connaissait d´ej`a des solutions it´eratives plus efficaces ; I on cherchait surtout des exemples simples pour illustrer les
concepts ;
I On va maintenant examiner des cas o`u la r´ecursivit´e se justifie mieux ;
G´ en´ eration de tous les mots binaires
I Notre but est d’´ecrire une fonction affichant tous les mots binaires sur n bits ;
Exemple 4
>>> generer_mots_binaires(2)
00 01 10 11
>>> generer_mots_binaires(3)
000 001 010 011 100 101 110 111
I Pour r´esoudre le probl`eme r´ecursivement, d´ecoupons les mots comme les listes ; un mot binaire de n bits est :
1. soit vide (sin= 0) ;
2. soit un0ou un1suivi d’un mot binaire den−1 bits.
41
G´ en´ eration de tous les mots binaires
I Notre but est d’´ecrire une fonction affichant tous les mots binaires sur n bits ;
Exemple 4
>>> generer_mots_binaires(2)
00 01 10 11
>>> generer_mots_binaires(3)
000 001 010 011 100 101 110 111
I Pour r´esoudre le probl`eme r´ecursivement, d´ecoupons les mots comme les listes ; un mot binaire de n bits est :
1. soit vide (sin= 0) ;
2. soit un0ou un1suivi d’un mot binaire den−1 bits.
G´ en´ eration de tous les mots binaires
I Notre but est d’´ecrire une fonction affichant tous les mots binaires sur n bits ;
Exemple 4
>>> generer_mots_binaires(2)
00 01 10 11
>>> generer_mots_binaires(3)
000 001 010 011 100 101 110 111
I Pour r´esoudre le probl`eme r´ecursivement, d´ecoupons les mots comme les listes ; un mot binaire de n bits est :
1. soit vide (sin= 0) ;
2. soit un0ou un1suivi d’un mot binaire den−1 bits.
43
G´ en´ eration de tous les mots binaires
I Notre but est d’´ecrire une fonction affichant tous les mots binaires sur n bits ;
Exemple 4
>>> generer_mots_binaires(2)
00 01 10 11
>>> generer_mots_binaires(3)
000 001 010 011 100 101 110 111
I Pour r´esoudre le probl`eme r´ecursivement, d´ecoupons les mots
2. soit un0ou un1suivi d’un mot binaire den−1 bits.
G´ en´ eration de tous les mots binaires
I Notre but est d’´ecrire une fonction affichant tous les mots binaires sur n bits ;
Exemple 4
>>> generer_mots_binaires(2)
00 01 10 11
>>> generer_mots_binaires(3)
000 001 010 011 100 101 110 111
I Pour r´esoudre le probl`eme r´ecursivement, d´ecoupons les mots comme les listes ; un mot binaire de n bits est :
1. soit vide (sin= 0) ;
2. soit un0ou un1suivi d’un mot binaire den−1 bits.
45
G´ en´ eration de tous les mots binaires
Comment trouver une formulation r´ecursive ? Exemple 5 (mots binaires de longueur 3)
1
1 1⇒ 111
0⇒ 110
0 1⇒ 101
0⇒ 100 0
1 1⇒ 011
0⇒ 010
0 1⇒ 001
0⇒ 000
G´ en´ eration de tous les mots binaires
Comment trouver une formulation r´ecursive ? Exemple 5 (mots binaires de longueur 3)
1
1 1⇒ 111
0⇒ 110
0 1⇒ 101
0⇒ 100 0
1 1⇒ 011
0⇒ 010
0 1⇒ 001
0⇒ 000
47
G´ en´ eration de tous les mots binaires
Comment trouver une formulation r´ecursive ? Exemple 5 (mots binaires de longueur 3)
1
1 1⇒ 111
0⇒ 110
0 1⇒ 101
0⇒ 100 0
1 1⇒ 011
0⇒ 010
0 1⇒ 001
0⇒ 000
G´ en´ eration de tous les mots binaires
Comment trouver une formulation r´ecursive ? Exemple 5 (mots binaires de longueur 3)
1
1 1⇒ 111
0⇒ 110
0 1⇒ 101
0⇒ 100 0
1 1⇒ 011
0⇒ 010
0 1⇒ 001
0⇒ 000
49
G´ en´ eration de tous les mots binaires
Comment trouver une formulation r´ecursive ? Exemple 5 (mots binaires de longueur 3)
1
1 1⇒ 111
0⇒ 110
0 1⇒ 101
0⇒ 100 0
1 1⇒ 011
0⇒ 010
0 1⇒ 001
0⇒ 000
G´ en´ eration de tous les mots binaires
Comment trouver une formulation r´ecursive ? Exemple 5 (mots binaires de longueur 3)
1
1 1⇒ 111
0⇒ 110
0 1⇒ 101
0⇒ 100 0
1 1⇒ 011
0⇒ 010
0 1⇒ 001
0⇒ 000
51
G´ en´ eration de tous les mots binaires
Comment trouver une formulation r´ecursive ? Exemple 5 (mots binaires de longueur 3)
1
1 1⇒ 111
0⇒ 110
0 1⇒ 101
0⇒ 100 0
1 1⇒ 011
0⇒ 010
0 1⇒ 001
0⇒ 000
G´ en´ eration de tous les mots binaires
I Rappel : mot de longueurn = lettre + mot de longueurn−1 ;
I Les mots sont binaires, donc chaque lettre est un 0 ou un 1 ; I D`es lors, pour g´en´erer tous les mots binaires de longueur n :
I on g´en`ere tous les mots commen¸cant par 0 ; I on g´en`ere tous les mots commen¸cant par 1 ;
I et on compl`ete le sous-mot de longueurn−1 r´ecursivement ;
I Quelles sont les conditions d’arrˆet ?
I quand on a g´en´er´e un mot en entier : on l’affiche ; I quand on a g´en´er´e tous les mots : on s’arrˆete ;
53
G´ en´ eration de tous les mots binaires
I Rappel : mot de longueurn = lettre + mot de longueurn−1 ; I Les mots sont binaires, donc chaque lettre est un 0 ou un 1 ;
I D`es lors, pour g´en´erer tous les mots binaires de longueur n :
I on g´en`ere tous les mots commen¸cant par 0 ; I on g´en`ere tous les mots commen¸cant par 1 ;
I et on compl`ete le sous-mot de longueurn−1 r´ecursivement ;
I Quelles sont les conditions d’arrˆet ?
I quand on a g´en´er´e un mot en entier : on l’affiche ; I quand on a g´en´er´e tous les mots : on s’arrˆete ;
G´ en´ eration de tous les mots binaires
I Rappel : mot de longueurn = lettre + mot de longueurn−1 ; I Les mots sont binaires, donc chaque lettre est un 0 ou un 1 ; I D`es lors, pour g´en´erer tous les mots binaires de longueur n :
I on g´en`ere tous les mots commen¸cant par 0 ; I on g´en`ere tous les mots commen¸cant par 1 ;
I et on compl`ete le sous-mot de longueurn−1 r´ecursivement ; I Quelles sont les conditions d’arrˆet ?
I quand on a g´en´er´e un mot en entier : on l’affiche ; I quand on a g´en´er´e tous les mots : on s’arrˆete ;
55
G´ en´ eration de tous les mots binaires
I Rappel : mot de longueurn = lettre + mot de longueurn−1 ; I Les mots sont binaires, donc chaque lettre est un 0 ou un 1 ; I D`es lors, pour g´en´erer tous les mots binaires de longueur n :
I on g´en`ere tous les mots commen¸cant par 0 ;
I on g´en`ere tous les mots commen¸cant par 1 ;
I et on compl`ete le sous-mot de longueurn−1 r´ecursivement ; I Quelles sont les conditions d’arrˆet ?
I quand on a g´en´er´e un mot en entier : on l’affiche ; I quand on a g´en´er´e tous les mots : on s’arrˆete ;
G´ en´ eration de tous les mots binaires
I Rappel : mot de longueurn = lettre + mot de longueurn−1 ; I Les mots sont binaires, donc chaque lettre est un 0 ou un 1 ; I D`es lors, pour g´en´erer tous les mots binaires de longueur n :
I on g´en`ere tous les mots commen¸cant par 0 ; I on g´en`ere tous les mots commen¸cant par 1 ;
I et on compl`ete le sous-mot de longueurn−1 r´ecursivement ; I Quelles sont les conditions d’arrˆet ?
I quand on a g´en´er´e un mot en entier : on l’affiche ; I quand on a g´en´er´e tous les mots : on s’arrˆete ;
57
G´ en´ eration de tous les mots binaires
I Rappel : mot de longueurn = lettre + mot de longueurn−1 ; I Les mots sont binaires, donc chaque lettre est un 0 ou un 1 ; I D`es lors, pour g´en´erer tous les mots binaires de longueur n :
I on g´en`ere tous les mots commen¸cant par 0 ; I on g´en`ere tous les mots commen¸cant par 1 ;
I et on compl`ete le sous-mot de longueurn−1 r´ecursivement ;
I Quelles sont les conditions d’arrˆet ?
I quand on a g´en´er´e un mot en entier : on l’affiche ; I quand on a g´en´er´e tous les mots : on s’arrˆete ;
G´ en´ eration de tous les mots binaires
I Rappel : mot de longueurn = lettre + mot de longueurn−1 ; I Les mots sont binaires, donc chaque lettre est un 0 ou un 1 ; I D`es lors, pour g´en´erer tous les mots binaires de longueur n :
I on g´en`ere tous les mots commen¸cant par 0 ; I on g´en`ere tous les mots commen¸cant par 1 ;
I et on compl`ete le sous-mot de longueurn−1 r´ecursivement ; I Quelles sont les conditions d’arrˆet ?
I quand on a g´en´er´e un mot en entier : on l’affiche ; I quand on a g´en´er´e tous les mots : on s’arrˆete ;
59
G´ en´ eration de tous les mots binaires
I Rappel : mot de longueurn = lettre + mot de longueurn−1 ; I Les mots sont binaires, donc chaque lettre est un 0 ou un 1 ; I D`es lors, pour g´en´erer tous les mots binaires de longueur n :
I on g´en`ere tous les mots commen¸cant par 0 ; I on g´en`ere tous les mots commen¸cant par 1 ;
I et on compl`ete le sous-mot de longueurn−1 r´ecursivement ; I Quelles sont les conditions d’arrˆet ?
I quand on a g´en´er´e un mot en entier : on l’affiche ;
I quand on a g´en´er´e tous les mots : on s’arrˆete ;
G´ en´ eration de tous les mots binaires
I Rappel : mot de longueurn = lettre + mot de longueurn−1 ; I Les mots sont binaires, donc chaque lettre est un 0 ou un 1 ; I D`es lors, pour g´en´erer tous les mots binaires de longueur n :
I on g´en`ere tous les mots commen¸cant par 0 ; I on g´en`ere tous les mots commen¸cant par 1 ;
I et on compl`ete le sous-mot de longueurn−1 r´ecursivement ; I Quelles sont les conditions d’arrˆet ?
I quand on a g´en´er´e un mot en entier : on l’affiche ; I quand on a g´en´er´e tous les mots : on s’arrˆete ;
61
Impl´ ementation
I On ne g´en`ere pas chaque chaˆıne s´epar´ement, puisqu’on consommerait ainsiO(2n) en m´emoire ;
I Au lieu de cela, on utilise une liste dencaract`eres ;
I chaque mot se construit en modifiant cette liste ; I quand le mot est “prˆet”, on l’affiche ;
I Les appels r´ecursifs doivent savoir quelle position modifier ; I On rajoutera donc ce param`etre `a notre fonction r´ecursive ;
def generer_et_afficher_mots(liste, position, taille): if position >= taille:
print(''.join(liste)) return
for lettre in '01':
liste[position] = lettre
generer_et_afficher_mots(liste, position + 1, taille)
Impl´ ementation
I On ne g´en`ere pas chaque chaˆıne s´epar´ement, puisqu’on consommerait ainsiO(2n) en m´emoire ;
I Au lieu de cela, on utilise une liste dencaract`eres ;
I chaque mot se construit en modifiant cette liste ; I quand le mot est “prˆet”, on l’affiche ;
I Les appels r´ecursifs doivent savoir quelle position modifier ; I On rajoutera donc ce param`etre `a notre fonction r´ecursive ;
def generer_et_afficher_mots(liste, position, taille): if position >= taille:
print(''.join(liste)) return
for lettre in '01':
liste[position] = lettre
generer_et_afficher_mots(liste, position + 1, taille)
63
Impl´ ementation
I On ne g´en`ere pas chaque chaˆıne s´epar´ement, puisqu’on consommerait ainsiO(2n) en m´emoire ;
I Au lieu de cela, on utilise une liste dencaract`eres ; I chaque mot se construit en modifiant cette liste ;
I quand le mot est “prˆet”, on l’affiche ;
I Les appels r´ecursifs doivent savoir quelle position modifier ; I On rajoutera donc ce param`etre `a notre fonction r´ecursive ;
def generer_et_afficher_mots(liste, position, taille): if position >= taille:
print(''.join(liste)) return
for lettre in '01':
liste[position] = lettre
generer_et_afficher_mots(liste, position + 1, taille)
Impl´ ementation
I On ne g´en`ere pas chaque chaˆıne s´epar´ement, puisqu’on consommerait ainsiO(2n) en m´emoire ;
I Au lieu de cela, on utilise une liste dencaract`eres ; I chaque mot se construit en modifiant cette liste ; I quand le mot est “prˆet”, on l’affiche ;
I Les appels r´ecursifs doivent savoir quelle position modifier ; I On rajoutera donc ce param`etre `a notre fonction r´ecursive ;
def generer_et_afficher_mots(liste, position, taille): if position >= taille:
print(''.join(liste)) return
for lettre in '01':
liste[position] = lettre
generer_et_afficher_mots(liste, position + 1, taille)
65
Impl´ ementation
I On ne g´en`ere pas chaque chaˆıne s´epar´ement, puisqu’on consommerait ainsiO(2n) en m´emoire ;
I Au lieu de cela, on utilise une liste dencaract`eres ; I chaque mot se construit en modifiant cette liste ; I quand le mot est “prˆet”, on l’affiche ;
I Les appels r´ecursifs doivent savoir quelle position modifier ;
I On rajoutera donc ce param`etre `a notre fonction r´ecursive ;
def generer_et_afficher_mots(liste, position, taille): if position >= taille:
print(''.join(liste)) return
for lettre in '01':
liste[position] = lettre
generer_et_afficher_mots(liste, position + 1, taille)
Impl´ ementation
I On ne g´en`ere pas chaque chaˆıne s´epar´ement, puisqu’on consommerait ainsiO(2n) en m´emoire ;
I Au lieu de cela, on utilise une liste dencaract`eres ; I chaque mot se construit en modifiant cette liste ; I quand le mot est “prˆet”, on l’affiche ;
I Les appels r´ecursifs doivent savoir quelle position modifier ; I On rajoutera donc ce param`etre `a notre fonction r´ecursive ;
def generer_et_afficher_mots(liste, position, taille): if position >= taille:
print(''.join(liste)) return
for lettre in '01':
liste[position] = lettre
generer_et_afficher_mots(liste, position + 1, taille)
67
Impl´ ementation
I On ne g´en`ere pas chaque chaˆıne s´epar´ement, puisqu’on consommerait ainsiO(2n) en m´emoire ;
I Au lieu de cela, on utilise une liste dencaract`eres ; I chaque mot se construit en modifiant cette liste ; I quand le mot est “prˆet”, on l’affiche ;
I Les appels r´ecursifs doivent savoir quelle position modifier ; I On rajoutera donc ce param`etre `a notre fonction r´ecursive ; def generer_et_afficher_mots(liste, position, taille):
if position >= taille:
print(''.join(liste)) return
Fonction auxiliaire
Et comme d’habitude quand on rajoute des param`etres, on fournira une fonction auxiliaire :
def generer_mots_binaires(taille):
liste = ['0'] * taille
generer_et_afficher_mots(liste, 0, taille)
Il est facile de g´en´eraliser cette fonction `a d’autres usages : I g´en´erer tous les mots possibles sur n’importe quel alphabet
(mots de passe) ;
I g´en´erer tous les sous-ensembles d’un ensemble donn´e ; I . . .
69