La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Structures de données IFT-2000 Abder Alikacem La STL du C++. La récursivité Semaine 9 Département d’informatique et de génie logiciel Édition Septembre.

Présentations similaires


Présentation au sujet: "Structures de données IFT-2000 Abder Alikacem La STL du C++. La récursivité Semaine 9 Département d’informatique et de génie logiciel Édition Septembre."— Transcription de la présentation:

1 Structures de données IFT-2000 Abder Alikacem La STL du C++. La récursivité Semaine 9 Département d’informatique et de génie logiciel Édition Septembre 2009

2 Première partie Standard Template Library du C++ http://www.sgi.com/tech/stl/

3 STL : Standard Template Library  Conteneurs: En C++, une classe contenant un ensemble d’éléments d'un certain type est appelée conteneur. Ce sont donc eux qui contiendront les informations que l’on veut stocker.  Itérateurs: utilisés pour parcourir les items qui se retrouvent dans les conteneurs, ils jouent un peu le rôle de pointeurs sur des éléments d’un conteneur.  Algorithmes: utilisés pour faire des traitements sur les éléments qui se retrouvent dans les conteneurs.

4 Les conteneurs Les conteneurs sont classés suivant trois types:  Séquentiels  Adapteurs  Associatifs vector Tableau list Liste doublement chaînée slist List simplement chaînée queue File- FIFO (first-in, first-out) stack Pile - LIFO (last in, first out) set Ensemble avec des éléments distincts map Table de hachage

5 Conteneurs - Requis L’élément qui sera inclus dans un conteneur doit posséder:  constructeur de recopie  opérateur =  destructeur  un constructeur par défaut  un test d’égalité (opérateur ==)  un critère d’ordre (operateur < et autres)

6 Conteneurs séquentiels  vector: tableau dynamique qui ne se remplit qu’à la fin - extensible - accès aléatoire par index en O(1) - insertions et retraits à la fin en O(1) - insertions et retraits lents au milieu  list: liste doublement chaînée - accès au début et à la fin en O(1) - accès lent aux autres éléments Une séquence est un conteneur dans lequel les éléments sont organisés linéairement (il y a un premier, un suivant …, un dernier):

7 Liste (list) et vecteur (vector) Résumé des méthodes communes à vector et list void push back(const Object& x):Ajoute x à la fin du conteneur. Notons que si un objet est ajouté à la fin d'un vecteur alors sa taille est automatiquement augmentée. void pop back(): Enlève le dernier objet du conteneur const Object& back() const: Retourne l'objet situé µa la fin du conteneur const Object& front() const: Retourne l'objet situé au début du conteneur Pour les conteneurs de type list seulement void push front(const Object& x): Ajoute x au début du conteneur void pop front(): Enlève le premier objet du conteneur Pour les conteneurs de type vector seulement Object& operator[] (int i): Retourne l'objet situé à la position i du conteneur Object& at (int i): Comme le précédent mais avec un contrôle de la plage des valeurs. Déclenche une exception out of range lorsqu'un indice est incorrect. void resize( int nouvelle taille): Redéfini la taille du conteneur int capacity() const: Retourne la capacité du conteneur void reserve(int nouvelle capacite): Redéfini la capacité du conteneur

8 STL – L’adaptateur de conteneurs Stack ( la pile ) Dérive d’un deque Principe LIFO : push et pop à la même extrémité Queue ( la file ) Dérive d’un deque Principe FIFO (*)deque: tableau dynamique qui peut s’étendre par les deux extrémités. C’est un des conteneurs séquentiels de la STL

9 STL – L’adaptateur de conteneurs #include using namespace std; stack s; s.push(1); s.pop(); int n = s.size(); if(s.empty()){…} int i = s.top(); Lib « stack » stack est générique Déclaration (pile d’entiers) Empiler Dépiler Taille de la pile Pile vide? Sommet de la pile

10 STL – L’adaptateur de conteneurs #include using namespace std; queue f; int n =f.size(); f.push(10); f.pop(); int tete =f.front(); int fin = f.back(); Lib « queue » queue est générique Déclaration Taille Enfiler Défiler Tête de la file Fin de la file

11 Conteneurs associatifs Deux types de conteneur associatif essentiellement  set: les éléments sont triés et ne peuvent apparaître qu’une seule fois  La valeur est confondue avec la clé  Normalement implémenté en un arbre équilibré, fournit donc un algorithme efficace pour la rercherche d’une valeur  map: les éléments sont des paires clé/valeur et triés en fonction de la clé; chaque clé ne peut apparaître qu’une seule fois

12 Les itérateurs Exemple d’itérateur

13 Les itérateurs int c[5] = {3,4,5,6,7}; int* it=&c[0]; int* itFin = &c[5]; //Itérateur de fin de conteneur Tester si on a fini de parcourir le conteneur : it!= itFin void affiche( int* itDebut, int* itFin) { while( itDebut!= itFin) { cout << *itDebut; itDebut++; } } Exemple d’itérateur

14 Les itérateurs Chaque conteneur fourni un type d’itérateur Exemple le type list donne un itérateur de type : list :: iterator.  Tous les conteneurs offrent les mêmes fonctions de base permettant aux itérateurs d’accéder aux éléments begin() Retourne un itérateur pointant au premier élément du conteneur end() Retourne un itérateur pointant après le dernier élément du conteneur

15 Les itérateurs #include using namespace std; int main( ) { list list1; for (int i = 1; i<=40; i++) list1.push_back(i+i); list :: iterator i; //reverse_iterator //const_iterator for (i = list1.begin( ); i!=list1.end( ); i++) cout <<*i << “ “ ; return 0 ; }

16 Les algorithmes  La STL fournit un nombre important d’algorithmes génériques les plus utilisés, tels que les algorithmes de parcours, de recherche et de tri. Ils s’appliquent sur les conteneurs.  Les algorithmes ne sont pas des fonctions membres des classes des conteneurs. Ce sont plutôt des fonctions globales qui opèrent avec des intérateurs.  Pour manipuler cette bibliothèque, il suffit d‘incorporer dans l’entête #include  Quelques exemples d’algorithmes…

17 Les algorithmes Comparaison élément à élément le contenu de deux conteneurs. equal Compter l’apparition d’une valeur dans une séquence. count Trouver la première occurrence d’une valeur donnée. find for_each Réalise sur tous les éléments l’opération passée en paramètre sort trie les éléments remove Supprimer toutes les occurences d’un élément

18 Les foncteurs  Un foncteur est un objet se comportant comme une fonction  Repose sur la surcharge de l’opérateur () class PrintInt { public: void operator() (int elem) { cout << elem << “ “; } }; int main() { vector coll;... for_each (coll.begin(), coll.end(), PrintInt()); cout << endl; return 0; }

19 Les foncteurs void ajouter10(int & elem) { elem += 10; } int main() { vector unTableau;... for_each(unTableau.begin(), unTableau.end(), ajouter10);... } template void ajouter(int & elem) { elem += laValeur; } int main() { vector unTableau;... for_each(unTableau.begin(), unTableau.end(), ajouter );... } class Ajouter { public: Ajouter(int v) : laValeur(v) {} void operator()(int&elem)const { elem += laValeur; } private: int laValeur; }; int main() { vector unTableau; … int increment; cin >> increment; for_each(unTableau.begin(), unTableau.end(), Ajouter(increment)); … } …connue à l’exécution …connue à la compilation Valeur connue d’avance Exemple. Ajout d’une valeur à tous les éléments d’un vector

20 Deuxième partie  Rappel des notions de base  Limitations (suite de Fibonacci)  Sous-séquence de somme maximale  Backtracking

21 Notions de base Définition Un objet est récursif s'il est défini à partir de lui-même. Une fonction est récursive si elle peut s'appeler elle-même de façon directe ou indirecte. Les règles qui régissent la récursivité 1.Trouver la récursion 2.Présence de cas de base pouvant être résolu sans récursivité 3.Toujours progresser vers le cas de base à chaque appel récursif 4.Vérifier que les appels récursifs progressent réellement vers le cas de base. 5.Ne jamais dédoubler du travail dans des appels récursifs différents (voir la fonction récursive de Fibonacci).

22 Récursivité Structure générale d’une fonction récursive { ! if(/* !condition de convergence */) …; if(/*condition d’arrêt*/) return(/*Ce qu’elle doit retourné*/); else appel récursif } Traitement

23 Fonction récursive factorielle Soit la fonction Factorielle, effectuant l’opération n! Règle récursive : fact(n) = n * fact (n-1) Condition d’arrêt : fact (0) =1 Condition de convergence: n  0 int fact (int n){ if (n < 0) throw logic_error(  Fact:argument < 0  ); if (n = = 0) return 1; else return (n * fact (n-1)); }

24 Avantages et inconvénients Solution naturelle et facile à concevoir  si la fonction est récursive  quand la structure de données traitée est récursive Avantages  Formulation compacte, claire et élégante. Désavantages  Possibilité de grande occupation de la mémoire.  Temps d'exécution peut être plus long.

25 Limitations: Fonction récursive Fibonnacci long fibo (long valeur) { if (valeur< 0) throw logic_error(  Fibo:argument < 0  ); if (valeur <= 1) return valeur; else return(fibo(valeur-1) + fibo(valeur-2)); } Soit la fonction Fibo (Fibonacci), effectuant l’opération f(n) = f(n-1) + f(n-2)

26 Exécution de Fibonnacci Soit les appels effectués pour fibo(n) : fibo(n) fibo(n-2) fibo(n-4) fibo(n-6)fibo(n-5) fibo(n-3) fibo(n-1) fibo(n-2)fibo(n-3)  Règle 5: Ne jamais dupliquer le travail par la résolution d’une même instance d’un problème dans plusieurs appels récursifs. fibo(n-3) fibo(n-4)

27 Champs d'application des algorithmes récursifs  Structures de données définies récursivement (listes, arbres, etc..)  Équations de récurrence;  Rétroaction ("backtracking").  … Nous allons voir ensemble quelques exemples typiques impliquant la récursivité.

28 Sous-séquence de somme maximale Définition (rappel du laboratoire#1): Étant donnée des entiers (possiblement négatifs) A 1, A 2,..., A N, trouver et identifier la séquence correspondante à la valeur maximale de. Résolution (algorithme#4): Application de la technique de diviser et régner (divide-and-conquer), une Méthode de résolution de problèmes basée sur la récursivité:  Diviser en plusieurs sous problèmes résolus récursivement.  régner, où la solution du problème original est composé de la solution des sous-problèmes.

29 Sous-séquence de somme maximale Rappel. Algorithme #1 Entrée : séquence de n nombres Sortie : la sous-séquence (debut, fin, somme) de somme maximale sousSequence = (0, 0, sequence[0]) //initialisation for i = 0 to n-1 for j = i to n-1 { somme = 0 for k = i to j somme = somme + sequence[k] Si somme > sousSequence.somme sousSequence = (i, j, somme) }  Chercher pour tous les débuts possibles, et pour toutes les fins possibles pour un tel début (sans répétition).  La boucle la plus intérieure est inutile car pour calculer la somme à "position+1", il suffit d'ajouter sequence[position+1] à l'ancienne somme.

30 Sous-séquence de somme maximale Rappel. Algorithme #2 Entrée : séquence de n nombres Sortie : la sous-séquence (debut, fin, somme) de somme maximale sousSequence = (0, 0, sequence[0]) //initialisation for i = 0 to n-1 { somme = 0 for j = i to n-1 { somme = somme + sequence[j] if (somme > sousSequence.somme) sousSequence = (i, j, somme) }

31 Sous-séquence de somme maximale Rappel. Algorithme #3 On cherche un maximum. Si on trouve une sous-séquence initiale de somme inférieure (ou égale) à 0, on peut ignorer cette sous-séquence car elle apporte moins à la somme totale que de commencer juste après elle. Entrée : séquence de n nombres Sortie : la sous-séquence (debut, fin, somme) de somme maximale sousSequence = (0, 0, sequence[0]) //initialisation i=0; somme = 0 for j = 0 to n-1 { somme = somme + sequence[j] if (somme > sousSequence.somme) sousSequence = (i, j, somme) if (somme <= 0) { i = j + 1; somme = 0; } } 4, -1, 34, -5, 3

32 Sous-séquence de somme maximale Algorithme #4. Cas possibles:  Cas 1: La séquence est situé dans la première moitié.  Cas 2: La séquence est situé dans la deuxième moitié.  Cas 3: La séquence commence dans la première moitié et se termine dans la deuxième moitié. Sommaire de l’algorithme: 1.Déterminer récursivement la sous-séquence de somme maximale uniquement dans la première moitié. 2.Déterminer récursivement la sous-séquence de somme maximale uniquement dans la deuxième moitié. 3.Avec deux boucles consécutives, déterminer la sous-séquence de somme maximale qui débute dans la première moitié et qui termine dans la deuxième moitié. 4.Choisir la somme la plus élevée des trois.

33 SousSequence trancheMax4(Sequence t, int d, int f) { SousSequence rep = { 0, 0, t[0] }; int m = (d+f)/2; if(d==f){rep.debut=d; rep.fin=f; rep.somme= t[d]; return rep;} Sousequence sm1 = trancheMax4(t, d, m); Sousequence sm2 = trancheMax4(t, m+1, f); int s1=t[m]; int s1m=s1; int dmg=m; for(int k = m-1; k>=d; --k) { s1+=t[k]; if(s1>s1m){s1m=s1; dmg=k;} } int s2=t[m+1]; int s2m=s2; int dmd=m+1; for(int k = m+2; k<=f; ++k){ s2+=t[k]; if(s2>s2m){s2m=s2; dmd=k;} } int sm3 = s1m+s2m; if(sm1.somme>=sm2.somme && sm1.somme>=sm3){ return sm1;} if(sm2.somme>=sm1.somme && sm2.somme>=sm3){ return sm2;} rep.debut= dmg; rep.fin = dmd; rep.somme= sm3; return rep; }

34 Sous-séquence de somme maximale (Exemple) 32-50 2 32-50 2 32-50 2 2-50 2 2 3 2 -5 0 012 000 -5 max(2,-5,2-5) 2 max(3,2,3+2) 3 0 max(-1,0,-1+0) 2 max(-1,2,-1+2) max(0,2,0+1) max(5,2,0+0 )=5

35 Algorithme à essais successifs (AES) Problématique  Pour résoudre certains types de problèmes, il peut être souvent utile de procéder à l'exploration systématique des différentes solutions possibles. Il est donc essentiel de développer des techniques algorithmiques qui permettent une telle exploration. AES ou encore algorithme de back tracking  idée : construire progressivement une solution à un problème donné en essayant toutes les possibilités à chaque étape de la construction.  Remarque : la complexité de ce genre d ’algorithme est de nature exponentielle => à utiliser si l ’on n ’en connaît pas de meilleur.  Exemple: calcul du trajet d’un robot dans un labyrinthe. Il s'agit de concevoir un algorithme qui permet à un robot de trouver un chemin menant à la sortie d'un labyrinthe. Pour ce faire le robot explore systématiquement les quatre directions vers lesquelles il peut se déplacer. De plus, afin d'éviter que le robot ne se retrouve sur des cases déjà explorées chacune de celles-ci seront marquées à mesure qu'elles sont visitées. C'est de façon récursive que les cases faisant partie du chemin seront identifiées.

36 Programmation du trajet d’un robot mobile #define Y 9 /* Les dimensions du labyrinthe */ #define X 7 char laby[X][Y] = { {'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'}, {'X', ' ', ' ', 'X', ' ', ' ', ' ', ' ', 'X'}, {'X', ' ', 'X', 'X', ' ', 'X', 'X', ' ', 'X'}, {'X', ' ', ' ', ' ', ' ', ' ', 'X', 'X', 'X'}, {'X', 'X', 'X', ' ', 'X', ' ', 'X', ' ', 'X'}, {'X', 's', ' ', ' ', ' ', ' ', ' ', ' ', 'X'}, {'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'}}; int main() { int i, j; bool Parcours(int x, int y); if (Parcours(1,1)) {// Imprimer le résultat de la recherche for (i = 0; i < X; i++, cout<<endl) for (j = 0; j < Y; j++) cout<<laby[i][j]; } else cout<<"Il n'existe aucun chemin.\n"; return 0; }

37 Retour en arrière - Exemple  Utiliser des appels récursifs et l’ordre d’appel suivant: Nord Sud Est Ouest 0123456789 A B S C D E F E G H I J

38 Retour en arrière - Exemple 0123456789 A B S C D E F E G H I J bool Parcours(int x, int y) { if (laby[x][y] == 's') { laby[x][y] = 'S'; return true; } else if (laby[x][y] == ' ') { laby[x][y] = 'o'; if (Parcours(x-1, y)) return(true); else if (Parcours(x+1, y)) return(true); else if (Parcours(x, y+1)) return(true); else if (Parcours(x, y-1)) return(true); else laby[x][y] = '-'; } return false; }

39 Retour en arrière - réponse 0123456789 A B C D E F G H I J X E S oo o o ooX X o o o o o ooo o oX o oo o ooo o o o oo oX Xo o

40 Structures de données IFT-2000 Abder Alikacem Semaine 10 Les algorithmes de recherche Département d’informatique et de génie logiciel Édition septembre 2009

41 Les algorithmes de recherche  Les algorithmes de recherche  La recherche séquentielle  La recherche dichotomique  Complexité des algorithmes de recherche  Recherche dichotomique et arborescence

42 La recherche séquentielle 314281412116910  meilleur cas=O(1)  pire cas=O(n)  en moyenne= O(n/2)  absences=O(n) Données pas triées 123468910111214  meilleur cas=O(1)  pire cas=O(n)  en moyenne= O(n/2)  absences=O(n/2) Données triées

43 Modèles d’implantation tableau : liste chaînée : 123468910111214 123468910111214

44 La recherche binaire  implantation en tableau = accès direct à n’importe quel élément  en regardant tout de suite au milieu, on peut éliminer la moitié des données 123468910111214

45 La recherche binaire 123468910111214 100

46 La recherche binaire 123468910111214 1005

47 La recherche binaire 123468910111214 1005

48 La recherche binaire 123468910111214 1005

49 La recherche binaire : 10 ? 123468910111214 1005

50 La recherche binaire : 10 ? 123468910111214 1005

51 La recherche binaire : 10 ? 123468910111214 123468910111214 1005 6

52 La recherche binaire : 10 ? 123468910111214 123468910111214 1005 6 8

53 La recherche binaire : 10 ? 123468910111214 123468910111214 1005 6 8

54 La recherche binaire : 10 ? 123468910111214 123468910111214 1005 6 8

55 La recherche binaire : 10 ? 123468910111214 123468910111214 123468910111214 1005 6 8 67

56 La recherche binaire : 10 ? 123468910111214 123468910111214 123468910111214 1005 6 8 67

57 La recherche binaire : 10 ? 123468910111214 123468910111214 123468910111214 1005 6 8 67

58 La recherche binaire : 10 ? 123468910111214 123468910111214 123468910111214 1005 6 8 67 1234689 111214 7

59 La recherche binaire : 10 ? 123468910111214 123468910111214 123468910111214 1005 6 8 67 1234689 111214 7

60 La recherche binaire : 9.5 ? 123468910111214 123468910111214 123468910111214 1005 6 8 67 1234689 111214 7 recherche séquentielle : (données triées) données présentes : O(n/2) données absentes : O(n/2) recherche binaire : (données triées) données présentes : O(log n) données absentes : O(log n) Tableau comparatif

61 Modèles d’implantation tableau : liste chaînée ? 123468910111214 123468910111214 100

62 Structures pointées 123468910111214 012345678910

63 Structures pointées 123468910111214 012345678910

64 Structures pointées 123468910111214 012345678910

65 Structures pointées 12346 8 910111214 01234678910

66 Structures pointées 12346 8 910111214 01234678910

67 Structures pointées 12346 8 910111214 01234678910

68 Structures pointées 12 3 46 8 910 11 1214 013467910

69 Structures pointées 12 3 46 8 910 11 1214 013467910

70 Structures pointées 12 3 46 8 910 11 1214 013467910

71 Structures pointées 1 2 3 4 6 8 9 10 11 12 14

72 Structures pointées 1 2 3 4 6 8 9 10 11 12 14

73 Structures pointées 1 2 3 4 6 8 9 10 11 12 14

74 Arbre binaire ! 1 2 3 4 6 8 9 10 11 12 14

75 Arbre = index 1 2 3 4 6 8 9 10 11 12 14


Télécharger ppt "Structures de données IFT-2000 Abder Alikacem La STL du C++. La récursivité Semaine 9 Département d’informatique et de génie logiciel Édition Septembre."

Présentations similaires


Annonces Google