Exercices de programmation en Python 1) Test d’appartenance Ecrire une fonction mem qui étant donnés une liste a et un objet x renvoie True ssi x est un élément de la liste. Corrigé Noter que la procédure s’interrompt dès qu’une occurrence de x est trouvée. def mem(a,x) : for k in range(0,len(a)) : if a[k] == x : return True return False Remarque : Les puristes considèrent (non sans raison) que les interruptions de boucles for sont des pratiques barbares de programmation. On pourrait ainsi proproser la variante suivante : def mem(a,x) : test = False ; n=len(a) ; k=0 while (not test) and k<n : if a[k] == x : test = True k += 1 return test Par exemple, print(mem([2,0,1,4],3)) a¢ che False. Remarque : En Python, le booléen (x in a) vaut True ssi x est un élément de la liste a: 2) Suite dé…nie par une relation de récurrence Ecrire une fonction suite qui étant donnés deux arguments n et a renvoie la valeur de un , où la suite (uk )k2N est la suite 1 a dé…nie par u0 = 1 et 8k 2 N, uk+1 = uk + : 2 uk Corrigé def suite(n,a) : u = 1 for k in range(0,n) : u = (u + a/u) / 2 return u Remarque : Par exemple, print(suite(10,2)) renvoie 1.414213562373095 ; en fait, on peut montrer que la suite (uk )k2N p converge vers a. 3) Maximum de deux entiers et maximum d’une liste (non vide) a) Ecrire une fonction maximum qui étant donnés deux entiers renvoie leur valeur maximale. b) Ecrire une fonction max qui étant donnée une liste non vide d’entiers renvoie leur valeur maximale. Par exemple, print(max([1,3,5,1])) a¢ che 5. Remarque : Cette fonction max est en fait déjà dé…nie en Python, avec la syntaxe max(iterable). Elle est aussi valable pour tous les itérables (tuples, chaînes, dictionnaires, etc ...). Corrigé def maximum(x,y) : if x>y : return(x) else : return(y) Remarque : Les mots-clés def, if, else doivent se trouver en première position, donc sur des lignes di¤érentes. def max(a) : n = len(a) ; m=a[0] for j in range(1,n) : if a[j]>m : m = a[j] return m 4) Nombre maximum de zéros (consécutifs) dans une liste On suppose que la fonction maximum dé…nie dans l’exercice précédent est connue. a) Ecrire une fonction nombre qui étant donnée une liste renvoie le nombre de zéros dans la liste. Par exemple, print(nombre([1,0,2,0,0,4])) renvoie 3. b) Ecrire une fonction consec qui étant donnée une liste renvoie le nombre maximum de zéros consécutifs dans la liste. Par exemple, print(nombre([1,0,2,0,0,4])) renvoie 2. Corrigé def nombre(a) : n = len(a) ; c=0 for j in range(0,n) : if a[j]==0 : c += 1 return c Remarque : On utilise un compteur c. On rappelle que c += 1 équivaut à c = c+1. def consec(a) : n = len(a) c=0 ; m=0 for j in range(0,n) : if a[j]== 0 : else : c += c c=0 ; m=max(m,c) return max(m,c) Commentaire : On utilise un compteur c dont la valeur correspond au nombre de zéros conséctifs dans la séquence en cours de lecture. On utilise aussi une variable m qui mémorise la longueur maximale des séquences déjà lues. Lorsqu’on lit une valeur non nulle, on met à jour m (en lui attirbuant max(m,c)), et on met le compteur à 0. Il faut faire attention à la dernière étape où on doit renvoyer max(m,c). 5) Tri par sélection a) Ecrire une fonction indMin on renvoie l’indice du minimum (en renvoyant le plus petit s’il en existe plusieurs). Par exemple, indMin([5,2,3,4,2]) renvoie 1 (les éléments sont indicés à partir de 0). b) Ecrire une procédure echange qui étant donnés une liste a et deux entiers i et j permute dans a les éléments d’indices i et j. Par exemple : a = [1,2,3,4,5] ; echange(a,0,2) ; print(a) a¢ che [3,2,1,4,5]. c) Ecrire une procédure tri qui étant donnée une liste a modi…e cette liste de sorte à trier ses éléments (sans modi…er l’ensemble de ses valeurs). On utilisera un tri par sélection (des minima) : Le principe de l’algorithme consiste à déterminer la position du plus petit élément et à le mettre en première position (par un échange), puis d’itérer le procédé sur le sous-tableau restant. Il faut (n (n 1) + (n 2) + ::: = 1 2 n(n 1) comparaisons pour déterminer la position du plus petit élément, donc il faut 1) comparaisons pour trier une liste selon ce procédé. Corrigé a) On utilise une variable mémorisant l’indice du plus petit élément déjà lu : def indMin(a) : n = len(a) k=0 for j in range(1,n) : if a[j] < a[k] : k = j return k b) Il y a plusieurs méthodes, puisque Python autorise les a¤ectations de couples (plus généralement de tuples) : def echange(a,i,j) : stock = a[i] ; a[i] = a[j] ; a[j] = stock def echange(a,i,j) : a[i],a[j] = a[j],a[i] c) On utilise deux boucles imbriquées : dans la i-ième boucle, on détermine (à l’aide de la boucle en j) la position k du plus petit élément dans le sous-tableau [ai ; ai+1 ; :::; an 1 ], puis d’échanger ai et ak . def tri(a) : n = len(a) for i in range(n) : k=i for j in range(i+1,n) : if a[j] < a[k] : k = j echange(a,i,k) Remarque : Ainsi, a=[1,3,2,2] ; tri(a) ; print(a) a¢ che [1; 2; 2; 3]: 6) Tests de permutation Il s’agit de déterminer si une liste de longueur n correspond à une permutation de f0; 1; :::; n entier compris entre 0 et (n 1g, c’est-à-dire si tout 1) apparaît une et une seule fois dans la liste. Il s’agit d’écrire une fonction à valeurs booléennes qui étant donnée une liste a de longueur n renvoie True ssi a est une permutation de f0; 1; :::; n 1g. On propose deux méthodes, la seconde étant plus e¢ cace que la première (le nombre d’opérations est moindre). a) Ecrire une première fonction test1 qui pour tout entier i 2 f0; 1; :::; n 1g, véri…e qu’il existe un unique élément de la liste a valant j, et interrompt la procédure dès que ce test est faux. La complexité dans le pire des cas est en O(n2 ). b) Ecrire une première fonction test2 qui pour tout entier i 2 f0; 1; :::; n 1g construit en temps linéaire O(n) le tableau b des occurrences, c’est-à-dire que b[j] vaut le nombre de termes de a valant j. On véri…e ensuite (en temps linéaire O(n)) que le tableau des occurrences ne contient que des 1. La complexité est O(n). Corrigé Noter au passage qu’une instruction comportant un return permet d’interromre une boucle for. def test1(a) : n=len(a) for i in range(n) : s=0 for j in a : if i==j : s+=1 if s != 1 : return False return True def test2(a) : n=len(a) # l’instruction [0]*n crée la liste de longueur n ne contenant que des 0 b = [0]*n for i in range(n) : occu[a[i]] += 1 return (occu == [1]*n) Remarque : En Python, on peut tester directement l’égalité de listes (et plus généralement de tout objet). En revanche, il faut avoir en tête que la complexité est proportionnelle à la longuer de la liste. 7) Recherche par dichotomie En Python, le quotient de la division euclidienne d’un entier par un autre s’obtient à l’aide de //. Ainsi, si m est un entier, (m//2) est égal à la partie entière E(m=2): On suppose donnés un nombre x et une liste a = (a0 ; a1 ; :::; an 1) de nombres classés par ordre croissant. On propose de déterminer si x est un élément de la liste par une méthode par dichotomie : Supposons connus deux entiers i et j tels que j i > 1 et ai < x < aj . On considère l’élément d’indice k = E( 12 (i + j)) : Il est situé (au mieux) au milieu du tableau composé des éléments dont les indices sont compris entre i et j. On compare x et ak . Si x < ak , alors ai < x < ak , et on peut itérer le procédé (si k i > 1). Si ak < x, alors ak < x < aj . Si ak = x, alors on renvoie True. Il est très important de comprendre qu’on renvoie False soit au début si x < a0 ou x > an deux indices i et j tels que j i 1 soit lorsqu’on aboutit à 1: Ecrire une fonction dicho, qui étant donnés une liste triée a et un nombre x renvoie True ssi x apparaît dans a. Corrigé def dicho(a,x) : i=0 ; j=len(a)-1 if (x-a[i])*(x-a[j])== 0 : return True if (x-a[i])*(x-a[j])> 0 : return False while j-i > 1 : k = (i+j)//2 if a[k] == x : return True if a[k] > x : j = k else : return False i = k
© Copyright 2024 ExpyDoc