Semaine 8 Retour sur les tableaux : fonctions et récursivité

Slides:



Advertisements
Présentations similaires
Paramètres et pointeurs
Advertisements

8. Les tableaux P. Costamagna – ISEN N1.
Regrouper des éléments de même type et pouvoir y accéder à laide dun identificateur et dun indice. Objectif des tableaux.
ALGORITHMES RECURSIFS
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();
La fonction alloue un bloc de taille size. Il faut indiquer la taille du bloc que l’on veut allouer. Le premier exemple: #include void main()
8PRO100 Éléments de programmation Les pointeurs de caractères.
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.
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.
Exercices sur les pointeurs. lireCar/remettreCar Lorsque l’on lit caractère par caractère, on ne peut pas savoir qu’on a atteint un caractère avant de.
L'exécution d'un programme nécessite l'utilisation des ressources de l'ordinateur : temps de calcul pour exécuter les opérations, et l'occupation de la.
C++ Les fonctions. Présentation Utilité : Dès qu'un programme dépasse la centaine de lignes de code, il est pratique de pouvoir le décomposer en plusieurs.
L'image: Le codage des images BacPro SEN Lycée Condorcet.
CINI – Li115 1 Semaine 9 Algorithmes de tri ● Introduction ● Tri à bulle ● - principe ● - algorithme ● - efficacité ● Tri par sélection ● - principe, algorithme,
Tableaux et Pointeurs Chaînes de Caractères Programmation Impérative II.
CINI – Li115 1 Semaine 3 Boucles (suite), tirages aléatoires, bibliothèque graphique ● Imbrication d'instructions if et for ● Boucles for imbriquées ●
CINI – Li115 1 Semaine 4 Révisions ● Questions de cours ● Types des expressions ● Déclaration de variables ● Instruction conditionnelle et boucles ● Structure.
CINI – Li115 1 Semaine 6 Les fonctions ● Pourquoi écrire des fonctions ? ● Définition de fonctions ● Fonction main ● Appels de fonctions ● Portée des variables.
CINI – Li115 1 Semaine 5 Les tableaux ● Qu'est-ce qu'un tableau ? ● Déclarer et initialiser un tableau ● Fixer la taille d'un tableau ● Opérations classiques.
CINI – Li115 1 Semaine 10 Les pointeurs ● Notion d'adresse ● Déclaration et utilisation de pointeurs ● "Types pointeur" et initialisation des pointeurs.
1 Programmation en C++ C++ de base ● Programme C++ ● Variables, objets, types ● Fonctions ● Namespace ● Tests ● Boucles ● Pointeurs, références.
1 © Copyright 2005, Philippe Arlotto tln.fr Creative Commons Attribution-ShareAlike 2.0 license 27/09/2016 Algorithmique & Langage.
1 Programmation en C++ C++ de base ● Programme C++ ● Variables, objets, types ● Types et opérations fondamentales ● Tests ● Boucles ● Pointeurs, références.
CINI – Li115 1 Semaine 11 Les pointeurs (suite) ● Tableaux et pointeurs ● Questions sur les pointeurs.
UE2 - M22 Licence acoustique
Tableaux en C Mardi 2/05.
Langages de programmation TP6
Algorithme de recherche
Suites ordonnées ou mettre de l’ordre
Les tableaux différencier les variables simples des variables indicées (ordonnées et numérotées) un identificateur unique désigne un ensemble, une collection.
Les Instructions Itératives (Les Boucles)
LES TABLEAUX EN JAVA.
Algorithmiques Abdelbasset KABOU
Eléments d’Informatique Cours11 – Allocation dynamique, listes chaînées Catherine Recanati.
Allocation dynamique de mémoire
Pointeurs et langage C.
Algorithmique Langage C
Semaine 11 Les pointeurs (suite)
Les fonctions.
Matrices, déclaration en CSharp
Gestion dynamique de la mémoire : new / delete
SIF-1053 Architecture de ordinateurs
Algorithmique & Langage C
VI. Tri par tas (Heap sort)
Programmation Impérative II
IFT1969 Programmation scientifique en C Michel Reid.
6. Les types utilisateurs et les structures de données
L ES I NSTRUCTIONS I TÉRATIVES (L ES B OUCLES ) Réalisé par : OUZEGGANE Redouane Département de Technologie Faculté de Technologie – Université A.Mira,
Cours N°9: Algorithmiques Les Tableaux 1
Les tableaux.
Programmation en C++ C++ de base
1 RECURSIVITE PRESENTATION Ch. PAUL ALGORITHMIQUE Présentation de la récursivité.
Exercice PHP DEUST TMIC
Eléments de base du langage C
Les structures de base Listes chainées. Listes Les listes(similaire aux tableaux) sont des structures informatiques qui permettent de garder en mémoire.
Cours Programmation en C. Traitement de l’information Catégorie d’information Les données Les résultats Les informations intermédiaires.
Chapitre 3: Les listes simplement chaînées A.ABDALI MIPC/MIP S
Information, Calcul, Communication
RABAH M ed Ali 2018/2019
Tris Simples/Rapides.
PROGRAMMATION ET ENSEIGNEMENT
Exercices récapitulatifs
Quelle est la valeur de S après exécution des instructions suivantes :
QCM Pointeurs 2 / Q1 On considère la déclaration suivante : char *ptc ; ptc peut contenir : 1) des valeurs de variables de type caractère 2) des adresses.
renvoie la moyenne d’un tableau d’entiers
Listes Chaînées.
Python Nicolas THIBAULT
Eléments de base du langage C
Type Tableau Partie 1 : Vecteurs
Tableaux : Algorithmes de recherches
Transcription de la présentation:

Semaine 8 Retour sur les tableaux : fonctions et récursivité Fonctions et tableaux Récursivité sur les tableaux

Fonctions et tableaux (1) Il est interdit de définir des fonctions qui retournent des tableaux ! En revanche, un tableau peut être passé en paramètre d'une fonction. #include <cini.h> #define TAILLE 7 void afficheTab(int tab[], int taille){ int i; for(i=0; i < taille; i++){ CINI_print_int(tab[i]); CINI_print_char(' '); } CINI_newline(); int main(){ int tab_int[] = {2, 4, 6, 9, 3, 6, 8}; afficheTab(tab_int,TAILLE); return 0;

Fonctions et tableaux (2) Attention : En C, un tableau est passé par référence : Un tableau stocke une suite d'éléments, ce ne sont pas ces éléments qui sont transmis mais une référence à l'accès de ces éléments (l'adresse mémoire du premier élément de la suite). Si on modifie un tableau dans une fonction, il ressort modifié de l'appel de la fonction (contrairement aux autres variables qui sont passées par valeur). On vous expliquera pourquoi bientôt …

Fonctions et tableaux (3) #include <cini.h> #define TAILLE 7 void ajouteTab(int tab[], int taille, int val){ int i; for(i=0; i < taille; i++){ tab[i] = tab[i] + val; } void afficheTab(int tab[], int taille){ CINI_print_int(tab[i]); CINI_print_char(' '); CINI_newline(); int main(){ int tab_int[] = {2, 4, 6, 9, 3, 6, 8}; afficheTab(tab_int,TAILLE); ajouteTab(tab_int, TAILLE, 2); afficheTab(tab_int, TAILLE); return 0; 2 4 6 9 3 6 8 4 6 8 11 5 8 10

Fonctions et tableaux (4) #include <cini.h> #define TAILLE 100 void initialise(int tab[], int taille, int min, int max){ int i; for(i=0; i < taille; i++){ tab[i] = CINI_random(min, max); } void afficheTab(int tab[], int taille){ CINI_print_int(tab[i]); CINI_print_char(' '); CINI_newline(); int main(){ int tab_int[TAILLE]; initialise(tab_int, TAILLE, 1, 50); afficheTab(tab_int, TAILLE); return 0; Tableau non initialisé Tableau initialisé

Fonctions et tableaux (5) Une fonction qui manipule un tableau peut retourner une valeur (autre qu'un tableau) : #include <cini.h> #define TAILLE 100 float initialise(int tab[], int taille, int min, int max){ int i, j; float s = 0; for(i=0; i < taille; i++){ j = CINI_random(min, max); tab[i] = j ; s = s + j; } return s/taille; void afficheTab(int tab[], int taille){ ... } int main(){ int tab_int[TAILLE]; float m; m = ajouteTab(tab_int, TAILLE, 1, 50); CINI_print_string("moyenne des elements du tableau :"); CINI_print_float(m); afficheTab(tab_int, TAILLE); return 0;

Récursivité sur les tableaux (1) Rappel sur le principe de la récursivité : Décomposer le problème en un problème plus simple → réduire la taille du problème considéré Pour la récursion sur des entiers : la taille du problème est définie par un entier, on réduit la valeur de cet entier à chaque appel récursif. Pour la récursion sur les tableaux : Soit on considère la taille du tableau, on réduit la taille du tableau considéré à chaque appel récursif Ou bien on utilise un ou des indices qui varient à chaque appel pour tendre vers la condition d'arrêt (dépendant des valeurs des indices).

Récursivité sur les tableaux (2) Exemple : Somme des N premiers éléments d'un tableau = dernier élément + la somme des N-1 premiers éléments du tableau. Somme des éléments d'un tableau de nombres : Soit N le nombre d'éléments dont on veut faire la somme (taille du tableau) Cas général : somme_elts = dernier_elt + somme_elts des N-1 premiers éléments du tableau Cas de base : somme_elts = 0, si N = 0

Récursivité sur les tableaux (3) Somme des éléments d'un tableau d'entiers : int sommeElt(int tab[], int taille){ if(taille == 0){ return 0; } else{ return (tab[taille-1] + sommeElt(tab, taille-1)); Attention : cette définition, suppose que la valeur du paramètre taille ne dépasse pas la taille réelle du tableau.

Récursivité sur les tableaux (4) Somme des éléments d'un tableau d'entiers : int tab[] = {2, 5, 9, 5, 16, 31}; sommeElt(tab, 6) 31 + sommeElt(tab, 5) 16 + sommeElt(tab, 4) 5 + sommeElt(tab, 3) 9 + sommeElt(tab, 2) 5 + sommeElt(tab, 1) 2 + sommeElt(tab,0) 2 + 0 5 + 2 9 + 7 5 + 16 16 + 21 31 + 37 68

Récursivité sur les tableaux (5) Que se passe-t-il si on modifie l'appel récursif ? int sommeElt(int tab[], int taille){ if(taille == 0){ return 0; } else{ return (tab[taille-1] + sommeElt(tab, taille+1)); Boucle infinie ou erreur de segmentation

Récursivité sur les tableaux (6) Calcul de la valeur maximum présente dans un tableau : int maxInt(int a, int b){ if(a > b){ return a; } else{ return b; int maxTab(int tab[], int taille){ if(taille == 1){ return tab[0]; return (maxInt(tab[taille-1], maxTab(tab, taille-1))); Attention : on suppose ici que le tableau n'est pas vide

Récursivité sur les tableaux (7) Calcul du max d'un tableau : int tab[] = {2, 5, 99, 5, 31}; maxTab(tab, 5) maxInt(31,maxTab(tab, 4)) maxInt(5, maxTab(tab, 3)) maxInt(99, maxTab(tab, 2)) maxInt(5, maxTab(tab, 1)) 2 maxInt(5, 2) maxInt(99,5) maxInt(5, 99) maxInt(31, 99) 99

Récursivité sur les tableaux (8) Palindromes : Un palindrome est un texte dont l'ordre des lettres est identique si on le lit de gauche à droite ou de droite à gauche. On peut représenter un texte par un tableau de caractères. On souhaite vérifier que le texte contenu dans un tableau de caractères est un palindrome. L'appel à palindrome(char tabChar[] , in taille) retourne true si tabChar contient un palindrome, false sinon. Cas de base ? Cas général ?

Récursivité sur les tableaux (9) Palindromes : Soit m le nombre de caractères examinés à partir de la gauche du texte. Initialement m vaut 0. On appelle palindrome(tabChar, taille, m) Cas de base : Si m == (taille / 2) alors retourner true Cas général : Si tabChar[m] == tabChar[taille - m - 1] alors Retourner palindrome(tabChar, taille, m+1) Sinon Retourner false

Récursivité sur les tableaux (10) Palindromes : #include <cini.h> bool palindrome(char tabChar[], int taille, int m){ if(m == (taille / 2)){ return true; } else{ if(tabChar[m] == tabChar[taille - m -1]){ return palindrome(tabChar, taille, m+1); return false; int main(){ char tabChar[] = {'l', 'a', 'v', 'a', 'l'}; bool res = palindrome(tabChar, 5 , 0); CINI_print_string("palindrome ? -> "); CINI_print_bool(res); CINI_newline(); return 0; palindrome ? -> true

Récursivité sur les tableaux (11) Recherche dichotomique : La recherche dichotomique est une méthode de recherche d'un élément dans un tableau trié. On considère des tableaux d'entiers triés en ordre croissant. On souhaite vérifier si un élément elem est présent dans le tableau tabInt. Principe : Soit deb l'indice du début de la zone considérée et fin l'indice de la fin de cette zone. Initialement, on considère tout le tableau deb= 0 et fin = taille -1 On va au fur et à mesure de l'algorithme réduire la taille de la zone envisagée (on modifie les valeurs de deb et fin).

Récursivité sur les tableaux (12) Principe (suite) : On calcule le milieu de cette zone : milieu = (deb+fin) / 2 Soit m la valeur de l'élément d'indice milieu. On compare elem (l'élément recherché) avec m. Si m == elem, l'élément recherché est trouvé. Sinon : Si m < elem, on ré-itère la recherche dans la deuxième moitié du tableau (deb = milieu + 1). Sinon, on ré-itère la recherche dans la première moitié du tableau (fin = milieu - 1).

Récursivité sur les tableaux (13) Recherche dichotomique, principe (suite) : Soit tabInt[] = { 2 , 4 , 9 , 15 , 24 , 45}; On recherche l'élément elem (par exemple 4). On utilise 2 variables deb et fin indiquant l'indice de début et l'indice de fin de la partie du tableau dans laquelle on fait la recherche. Initialement : deb = 0 fin = taille_du_tableau - 1 (dans l'exemple fin = 5) Remarque : L'algorithme est le même que le tableau ait un nombre pair ou impair d'éléments.

Récursivité sur les tableaux (14) Recherche dichotomique, principe (suite) : Initialement : tabInt[] = { 2 , 4 , 9 , 15 , 24 , 45}; elem = 4 deb = 0, fin = 5 On compare elem avec l'élément situé au milieu du tableau : tabInt[ (fin + deb) / 2] == elem → 9 == 4 → false Comme 9 > 4, on ré-itère la recherche dans la première moitié du tableau : deb = 0, fin = 1 tabInt[ (fin + deb) / 2] == elem → 2 == 4 → false Comme 2 < 4, on ré-itère la recherche dans la deuxième moitié de la partie du tableau qui vient d'être considérée: deb = 1, fin = 1 tabInt[ (fin + deb) / 2] == elem → 4 == 4 → true → élément trouvé

Récursivité sur les tableaux (15) Recherche dichotomique, principe (suite) : Initialement : tabInt[] = { 2 , 4 , 9 , 15 , 24 , 45}; elem = 45 deb = 0, fin = 5 On compare elem avec l'élément situé au milieu du tableau : tabInt[ (fin + deb) / 2] == elem → 9 == 45 → false Comme 9 < 45, on ré-itère la recherche dans la deuxième moitié du tableau : deb = 3, fin = 5 tabInt[ (fin + deb) / 2] == elem → 24 == 45 → false Comme 24 < 45, on ré-itère la recherche dans la deuxième moitié de la partie du tableau qui vient d'être considérée : deb = 5, fin = 5 tabInt[ (fin + deb) / 2] == elem → 45 == 45 → true → élément trouvé

Récursivité sur les tableaux (16) Recherche dichotomique, principe (suite) : Initialement : tabInt[] = { 2 , 4 , 9 , 15 , 24 , 45}; elem = 5 deb = 0, fin = 5 On compare elem avec l'élément situé au milieu du tableau : tabInt[ (fin + deb) / 2] == elem → 9 == 5 → false Comme 9 > 5, on ré-itère la recherche dans la première moitié du tableau : deb = 0, fin = 1 On réitère ... tabInt[ (fin + deb) / 2] == elem → 2 == 5 → false

Récursivité sur les tableaux (17) Comme 2 < 5, on ré-itère la recherche dans la deuxième moitié de la partie du tableau qui vient d'être considérée : tabInt[] = { 2 , 4 , 9 , 15 , 24 , 45}; elem = 5 deb = 1, fin = 1 On compare elem avec l'élément situé au milieu de la portion de tableau considérée : tabInt[ (fin + deb) / 2] == elem → 4 == 5 → false deb et fin ont la même valeur donc on ne peut plus réduire la partie du tableau dans laquelle on recherche l'élément → l'élément recherché n'est pas dans le tableau

Récursivité sur les tableaux (18) Recherche dichotomique, fonction : bool rech_dicho(int tabInt[], int taille, int elem, int deb, int fin){ int milieu = (deb+fin) /2; if(deb == fin){ return (tabInt[deb] == elem); } else { if(tabInt[milieu] == elem){ return true; if(tabInt[milieu] > elem){ return rech_dicho(tabInt, taille, elem, deb, milieu -1); return rech_dicho(tabInt, taille, elem, milieu +1, fin);

Récursivité sur les tableaux (19) #include <cini.h> bool rech_dicho(int tabInt[], int taille, int elem, int deb, int fin){ int milieu = (deb+fin) /2; if(deb == fin){ return (tabInt[deb] == elem); } else { if(tabInt[milieu] == elem){ return true; if(tabInt[milieu] > elem){ return rech_dicho(tabInt, taille, elem, deb, milieu -1); return rech_dicho(tabInt, taille, elem, milieu +1, fin); } int main(){ int tab[] = { 2 , 4 , 9 , 15 , 24 , 45}; bool res = rech_dicho(tab, 6, 2, 0, 5); CINI_print_string("rech dicho -> "); CINI_print_int(res); CINI_newline(); return 0; Remarque : on peut omettre le paramètre taille