Algorithme et structure de données

Slides:



Advertisements
Présentations similaires
Premier programme en C :
Advertisements

Introduction au Langage C,C++
Algorithmique (suite)
Le Code de César Et son utilisation.
La classe String Attention ce n’est pas un type de base. Il s'agit d'une classe défini dans l’API Java (Dans le package java.lang) String s="aaa"; // s.
GEF 243B Programmation informatique appliquée Types dérivés, structures et tableaux §
Approfondissement du langage
(Classes prédéfinies – API Java)
1 Tableaux des objets C++ si on connaît le nombre dobjets nécessaires davance on peut utiliser des tableau dobjets dans les fonctions dusage class Personne.
Algorithme et structure de données
Les attributions de valeur (le signe =). Dans cette présentation, nous allons tenter de représenter ce qui se passe dans la mémoire de lordinateur quand.
Algorithme et programmation
Le codage Vigenère.
Regrouper des éléments de même type et pouvoir y accéder à laide dun identificateur et dun indice. Objectif des tableaux.
Cryptographie Mener des Activités en classe
Les méthodes en java Une méthode est un regroupement d’instructions ayant pour but de faire un traitement bien précis. Une méthode pour être utilisée.
Leçon 6 : Structures de données dynamiques IUP 2 Génie Informatique Méthode et Outils pour la Programmation Françoise Greffier.
La fonction alloue un bloc de taille size. Il faut indiquer la taille du bloc que lon veut allouer. Le premier exemple: #include void main()
TRAITEMENT DE STRUCTURES
EXEMPLE DE MESSAGE CRYPTE PUIS DECRYPTE avec la méthode RSA
Langage Oriente Objet Cours 2.
Base de programmation Script unity en c#.
Réalisé par: Jihen THOUIR Imen JENDOUBI Meriam BEN SALHA Marwa LAZHAR
IFT-2000: Structures de données
Structures de données IFT Abder Alikacem La classe string Département dinformatique et de génie logiciel Édition Septembre 2009 Département dinformatique.
Conteneurs STL.
Une nouvelle structure de données : les tableaux
Contrôle de types Les types en programmation Expressions de types Un contrôleur de types Equivalence de types Conversions de types Généricité.
IFT 6800 Atelier en Technologies d’information
COURS DE PROGRAMMATION ORIENTEE OBJET :
Standard Template Library
CSI1502 Principes fondamentaux en conception des logiciels
CSI 1502 Principes fondamentaux de conception de logiciels
Récursion IFT1025: Programmation 2 Jian-Yun Nie. Définition Le fait pour un programme ou une méthode de s'appeler lui-même. Par exemple –Définir la notion.
Tableaux Introduction aux tableaux à une dimension. Déclaration, stockage, initialisation et accès en lecture ou en écriture aux composantes d’un tableau.
Structures de données IFT-2000
Héritage et composition
Structures des données
Cours 7 Divers et exceptions. Chapitre V Enumeration, tableaux, conversion de types, noms.
Stocker plusieurs valeurs de même type dans une variable
Le langage C Structures de données
4 Introduction des objets. Les chaînes et tableaux
LES PILES ET FILES.
Les Pointeurs et les Tableaux Statiques et Tableaux Dynamiques
Notions de pointeurs en C
Le cryptage c’est tout un art
Programmation en Java Tableaux NGUYEN Thi Minh Tuyen
Labo II : Tableaux et pointeurs
Série S spécialité ISN Informatique et Sciences du Numérique
Labo 4 : Les structures et les entrées et sorties
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()
VOUS PENSIEZ POUVOIR PROTÉGER VOS DONNÉES AVEC LE CHIFFREMENT D’OFFICE ? CRYPTANALYSE DE MICROSOFT OFFICE 2003.
Strings et Tableaux en Java
Les opérateurs L’amitié Les opérateurs Introduction
8PRO100 Éléments de programmation Les tableaux multi-dimensionnels.
8PRO100 Éléments de programmation Les pointeurs de caractères.
Cours LCS N°4 Présenté par Mr: LALLALI
Conception de Programmes - IUT de Paris - 1ère année – Cours 6 - Les opérateurs L’amitié Les opérateurs –Introduction –Surcharge par fonction.
LIFI-Java 2004 Séance du Mercredi 29 sept. Cours 4.
Conception de Programmes - IUT de Paris - 1ère année Quelques éléments du langage C++ Les références La surcharge de fonctions Les fonctions «
Les bases de l’algorithmique
8PRO107 Éléments de programmation Les tableaux multidimensionnels.
Philippe Gandy - 22 septembre 2015 Basé sur les notes de cours de Daniel Morin et Roch Leclerc.
Master 1 SIGLIS Java Lecteur Stéphane Tallard Correction du TD Chapitre 3.
Sous-titre Disposition du titre.
Int 10. Int 6.
Disposition du titre Sous-titre.
Disposition du titre Sous-titre.
Disposition du titre Sous-titre.
Transcription de la présentation:

Algorithme et structure de données IUP1 Miage

Tableau à une dimension Tableau de trois caractères {’u’, ’b’, ’c’} t[0] t[1] t[2] char[] t={’u’, ’b’, ’c’}; Tableau de trois entiers int[] t={4, 100, 21};

Déclaration d’un tableau char[] t ; // création sans initialisation t=new char[3] ; // création avec initialisation t={’u’,’b’,’c’};

Parcourir un tableau char[] t = new char[3] ; for(int i=0 ; i< t.length ; i++){ t[i]=Console.readChar(”? ”); } t[i]=t[i]+1; S.o.p(t[i]);

Cryptographie : Codage de César Discipline incluant les principes, les moyens et les méthodes de transformation des données, dans le but de masquer leur contenu, d'empêcher leur modification ou leur utilisation illégale Décaler les lettres de l'alphabet de trois crans vers la gauche ABCDEFGHIJKLMNOPQRSTUVWXYZ DEFGHIJKLMNOPQRSTUVWXYZABC AVE CAESAR

Cryptographie : Codage de César Discipline incluant les principes, les moyens et les méthodes de transformation des données, dans le but de masquer leur contenu, d'empêcher leur modification ou leur utilisation illégale Décaler les lettres de l'alphabet de trois crans vers la gauche ABCDEFGHIJKLMNOPQRSTUVWXYZ DEFGHIJKLMNOPQRSTUVWXYZABC AVE CAESAR DYH FDHVDU

Crypter un message void crypter(char [] mess) { ????? } void deCrypter(char [] mess) {

Crypter un message void crypter(char [] mess) { char aux ; for(int i=0; i<mess.length; i++) { aux = (char) (mess[i]+3) ; if (aux > 'z') aux=(char)(aux - 26); mess[i]=aux; }

Décrypter un message void deCrypter(char [] mess) { char aux ; for(int i=0; i<mess.length; i++) { aux = (char)(mess[i]-3) ; if (aux < 'a') aux=(char)(aux + 26); mess[i]=aux; }

Crypter / décrypter … Chiffrer le message "OUI" avec un décalage de 10

Chercher un élément dans un tableau int indexOf(char[] t, char c){ int i=0; while(i<t.length && t[i]!=c) i++; if (i==t.length) return -1; else return i; }

Tableau à deux dimensions Notion mathématique de matrice Tableau de tableaux u b c t[0][0] t[0][1] t[0][2] x y z t[1][0] t[1][1] t[1][2] a z e t[2][0] t[2][1] t[2][2]

Déclaration d’un tableau char[][] t ; // création sans initialisation t=new char[3][3] ; // création avec initialisation t={{’u’,’b’,’c’}, {’x’,’y’,’z’}, {’a’,’z’,’e’}} ;

Parcourir un tableau char[][] t = new char[3][3] ; for(int l=0 ; l<3 ; l++){ for(int c=0 ; c<3 ; c++){ t[l][c]=Console.readChar(”? ”); }

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

Créer le tableau alphabet char[][] alphabet =new char[26][26] ; void initAlphabet(){ char debut='a', lettre ; for(int ligne=0;ligne<26;ligne++){ ???; for(int colonne=0;colonne<26;colonne++) { alphabet[ligne][colonne]= ???; if (lettre<'z') ???; else ???; }

Créer le tableau alphabet char[][] alphabet =new char[26][26] ; void initAlphabet(){ char debut='a', lettre ; for(int ligne=0;ligne<26;ligne++){ lettre=debut; for(int colonne=0;colonne<26;colonne++) { alphabet[ligne][colonne]=lettre; if (lettre<'z') lettre ++; else lettre='a'; } debut++;

Carré de Vigenère (1525-1596) Pour coder - ou décoder - un texte, on utilise un mot clef le tableau carré constitué de 26 alphabets décalés Et on code lettre à lettre : chiffré = clair + clef

Clair HELLOWORLD Clef ECSECSECSE Chiffré LGDPQOSTDH A B C D E F G H I J K L M N O P Q R S T U V W X Y Z Clair HELLOWORLD Clef ECSECSECSE Chiffré LGDPQOSTDH

Carré de Vigenère (1525-1596) Clair HELLOWORLD Clef ECSECSECSE Chiffré LGDPQOSTDH

Crypter/décrypter un message void crypter(char[] mess, char[] clef) { int l, c ; for(int i=0; i<mess.length; i++) { ??? } void deCrypter(char[] mess, char[] clef) { for(int i=0; i<mess.length; i++){

Crypter un message void crypter(char[] mess, char[] clef) { int l, c ; for(int i=0; i<mess.length; i++) { l=clef[i]-'a'; c=mess[i]-'a'; mess[i]=alphabet[l][c]; }

Décrypter un message void deCrypter(char[] mess, char[] clef) { for(int i=0; i<mess.length; i++){ mess[i]=(char)('a'+ indexOf(tabApha[clef[i]-'a'],mess[i])); }

Le choix de la clé correspond ici au choix des quatre entiers a,b,c,d Codage de Hill Coder simultanément des groupes de 2 lettres! Remplacer chaque lettre par son ordre dans l'alphabet : A devient 0, B devient 1,..., Z devient 25 Calculer pour chaque bloc de 2 nombres à coder x1x2, les combinaisons linéaires : y1 = ax1+bx2 y2 = cx1+dx2 Ramener les résultats y1 et y2 dans l’intervalle 0..25 en prenant leur reste dans la division par 26 Transformer y1 et y2 en lettres Le choix de la clé correspond ici au choix des quatre entiers a,b,c,d

Codage de Hill (main) void main(String str []) { // on suppose que le message a un nombre pair de caracteres char[] message= {'e','l','e','c','t','i','o','n'} ; int[] clef = {1,1,5,1}; if (! clefValide(clef)) S.o.p("LA CLEF N'EST PAS VALIDE !"); else { S.o.p("MESSAGE EN CLAIR : ");S.o.p(message); crypter(message,clef); S.o.p("MESSAGE CRYPTER : ");S.o.p(message); deCrypter(message,clef); S.o.p("MESSAGE DECRYPTER : ");S.o.p(message); }

Codage de Hill (crypter) void crypter(char[] message, int[] clef) { int taille=message.length ; int[] x = new int[taille] ; int[] y = new int[taille]; for(int i=0; i<taille; i++) x[i]=message[i]-'a'; for(int i=0; i<taille/2; i++) { y[2*i] =(clef[0]*x[2*i]+clef[1]*x[2*i+1])%26 ; y[2*i+1]=(clef[2]*x[2*i]+clef[3]*x[2*i+1])%26 ; } for(int i=0; i<taille; i++) message[i] =(char) (y[i]+'a');

Codage de Hill (decrypter) boolean clefValide(int[] clef){ int det=determinant(clef) ; // une clef est valide ssi // son determinant est premier avec 26 return (pgcd(det,26)==1) ; } void deCrypter(char[] message, int[] clef) { crypter(message, inverserClef(clef));

Codage de Hill (decrypter) int[] inverserClef(int[] clef) { int[] iClef= new int[clef.length]; int det =determinant(clef) ; int idet=iDeterminant(clef); iClef[0]=(clef[3]*idet)%26 ; // obtenir une valeur dans l'intervalle [0..25] int d=-clef[1]*idet ; while (d<0) {d=d+26;} iClef[1]=d%26; d=-clef[2]*idet ; while (d<0) {d=d+26;} iClef[2]= d%26; iClef[3]=(clef[0]*idet)%26 ; return iClef ; }

Codage de Hill (decrypter) int iDeterminant(int[] clef){ int d=determinant(clef); // calculer l'inverse de d dans Z/26Z // c'est a dire trouver un nombre id // tel que d*id=1+k*26 int id=1 ; while ((d*id)%26 !=1) id++; return id ; }

Voici mon tableau [I@18c3679 !!!! void main(String[] args) { int[] tab = {5, 2, 6}; S.o.p("Voici mon tableau" + tab); } [ --> Tableau I --> integer @ --> Adresse 18c3679 adresse en hexadécimal

Affection de tableaux void main(String[] args){ int[] t1 = {5, 2, 6}; S.o.p("Tableaux "+t1+","+t2); }

Affection de tableaux void main(String[] args){ int[] t1 = {5, 2, 6}; S.o.p("Tableaux "+t1+","+t2); } Tableaux [I@18c3679 , [I@18c3679

1 tableau ou 2 tableaux ? void main(String[] args){ int[] t1 = {5, 2, 6}; int[] t2 = t1; t2[1] = 8; S.o.p(t1[1]); }

1 tableau ou 2 tableaux ? void main(String[] args){ int[] t1 = {5, 2, 6}; int[] t2 = t1; t2[1] = 8; S.o.p(t1[1]); } 8

Egalité de tableaux ! void main(String[] args){ int[] t1 = {5, 2, 6}; int[] t2 = new int[t1.length]; for(byte i = 0; i < t1.length; i++){ t2[i] = t1[i]; S.o.p(t1[i]+" ? "+t2[i]); } S.o.p(t1 == t2);

Egalité de tableaux ! void main(String[] args){ int[] t1 = {5, 2, 6}; int[] t2 = new int[t1.length]; for(byte i = 0; i < t1.length; i++){ t2[i] = t1[i]; S.o.p(t1[i]+" ? "+t2[i]); } S.o.p(t1 == t2); 5 ? 5 2 ? 2 6 ? 6 false

Trier un tableau … Réorganiser une collection d'objets selon un ordre déterminé Les objets à trier font partis d'un ensemble muni d'une relation d'ordre total Méthode de tri indépendamment de la fonction d'ordre la seule opération nécessaire est de pouvoir comparer tout couple d'objets

Caractéristiques d'un tri Complexité algorithmique dans le pire des cas : le nombre d'opérations effectuées dans le pire des cas pour trier un ensemble de n éléments Complexité en moyenne : le nombre d'opérations effectuées en moyenne pour trier un ensemble de n éléments

Comment représenter la complexité ? Soit n la taille du tableau à trier Complexité en O(n) (complexité linéaire) : il faut 2 fois plus de temps pour trier n*2 éléments que n il faut 10 fois plus de temps pour trier n*10 éléments que n Complexité en O(n²) il faut 2² fois plus de temps pour trier n*2 éléments que n il faut 10² fois plus de temps pour trier n*10 éléments que n O(n) << O(n log n) << O(n²)

Caractéristiques d'un tri Mémoire nécessaire : hormis la mémoire nécessaire pour stocker les éléments à trier, l'algorithme nécessite-t-il une quantité de mémoire supplémentaire dépendant du nombre d'éléments à trier ? Stabilité : lorsque deux éléments sont équivalents pour la relation d'ordre, conserver l'ordre dans lequel ces deux éléments se trouvaient avant le tri

Tri par Insertion Principe : c'est le tri que l’on utilise quand on a des dossiers à classer On prend un dossier et on le met à sa place parmi les dossiers déjà triés Puis on recommence avec le dossier suivant

Pour procéder à un tri par insertion, il suffit de … Parcourir le tableau : on prend les éléments dans l'ordre Comparer chaque élément avec les éléments précédents jusqu'à trouver sa place Décaler les éléments du tableau pour insérer l'élément considéré à sa place dans la partie déjà triée

Tri par Insertion : exemple Original : 3 9 6 1 2 insérons 9 : 3 9 6 1 2 insérons 6 : 3 6 9 1 2 insérons 1 : 1 3 6 9 2 insérons 2 : 1 2 3 6 9

Tri par insertion (algorithme) void main(String[] args){ int[] tab={2,7,1,8,3,0,1}; afficherTableau(tab); triInsertion(tab); }

Tri par insertion (version 1) void triInsertion(int[] t){ int taille=t.length ,j , aux ; for(int i=1;i<taille;i++){ // on commence à 1 // inserer t[i] dans t[0..i-1] j=0 ; while (t[j]<t[i]) j++ ; // t[j]>=t[i] // decalage vers la droite sur t[j-1..i] aux = t[i]; for(int k=i;k>j;k--) t[k]=t[k-1]; t[j]=aux ; }

Propriétés du Tri par Insertion Ne nécessite par de connaître (stoker) tous les éléments des le début Soit n le nombre d’éléments à trier Le nombre de comparaisons nécessaires est de l'ordre de n²/4 Le nombre moyen d'échanges est de l'ordre de n²/2 Le pire cas est obtenu avec un tableau en ordre inverse le meilleur cas avec un tableau déjà ordonné Intéressant dans le cas où le tableau est déjà presque ordonné

Décalages en même temps que la recherche du point d’insertion void triInsertion2(int[] t){ int taille=t.length, j , aux ; for(int i=1;i<taille;i++) { //on commence à 1 aux = t[i]; j=i-1 ; while (j>=0 && t[j]>aux) {t[j+1]=t[j];j--;} // j==-1 || t[j]<=aux t[j+1]=aux; }

Tri par insertion en réalisant des échanges (version 3) void triInsertion3(int[] t){ int taille=t.length, j , aux ; for(int i=1;i<taille;i++){ //on commence à 1 aux = t[i]; j=i-1 ; while (j>=0 && t[j]>aux) {echanger(t,j+1,j);j--;} }

Tri par sélection Rechercher le plus petit que l'on va replacer à sa position finale c'est-à-dire en premier, puis rechercher le second plus petit que l'on va replacer également à sa position finale c'est-à-dire en second, etc, jusqu'à ce que le tableau soit entièrement trié

Tri par sélection : exemple Original : 3 9 6 1 2 plus petit est 1 : 1 9 6 3 2 plus petit est 2 : 1 2 6 3 9 plus petit est 3 : 1 2 3 6 9 plus petit est 6 : 1 2 3 6 9

Propriétés du tri par sélection Soit n le nombre d’éléments à trier Nombre de comparaisons nécessaires pour un tri est de n(n-1)/2 Nombre d'échanges est de l'ordre de n

Sélectionner pour trier public static void main(String[] args){ int[] tab = {-2, 0, 8 ,7 ,1, -5, 12, 10, 25, 5} ; final int N=tab.length ; int indMin ; int aux ; // Trier tab[0..N-1] for(int k=0 ; k<N-1 ; k++){ // chercher la place IndMin du plus petit élément // du sous tableau tab[k..N-1] indMin=k ; for(int j=k+1 ; j<N ; j++) { if(tab[j] < tab[indMin]) indMin=j;} // échanger tab[indMin] avec tab[k] aux = tab[indMin]; tab[indMin] = tab[k]; tab[k] = aux; }

Comparaison des tris Les tris par Sélection et par Insertion ont une efficacité Semblable Ils ont chacun une boucle externe qui parcourt tous les éléments, et une boucle interne qui compare les valeurs de la boucle externe avec presque toutes les valeurs de la liste Donc approximativement n2 comparaisons sont nécessaires pour trié une liste de taille n Ces tris sont de l’ordre de n2 D’autres tris sont plus efficace : ordre de n log2 n

Tri à Bulles (bubble sort) L'idée est de parcourir le tableau autant fois que nécessaire en échangeant 2 à 2 les éléments consécutifs qui ne sont pas dans le bon ordre. c'est-à-dire si t[j-1] > t[j], alors on échange t[j-1] et t[j]

Tri à Bulles : les éléments les plus légers remontent vers la surface Après le premier passage, le plus grand élément se trouve rangé en haut du tableau, on peut donc l'exclure dans l'itération suivante Le même raisonnement s'applique sur les itérations suivantes : à chaque itération on diminue de 1 la taille de la partie à traiter du tableau Plusieurs élément du « haut » du tableau peuvent se trouver rangés dans l'ordre ; on peut donc optimiser le traitement en s'arrêtant au dernier élément déplacé de l'itération précédente, ce qui peut être fait en ajoutant l'instruction

Tri à Bulles : exemple 23 10 75 5 37 49 53 10 23 75 5 37 49 53 10 23 5 75 37 49 53 10 23 5 37 75 49 53 10 23 5 37 49 75 53 10 23 5 37 49 53 75

Tri Bulles void triBulles(int[] t){ int haut=t.length-1, while (haut>0) { for(int j=0 ; j<haut ; j++){ if(t[j]>t[j+1]) {echanger(t, j, j+1);} } haut--;

Permuter 2 éléments dans un tableau void echanger(int[] t,int i,int j){ int aux =t[i]; t[i]=t[j]; t[j]=aux; }

Complexité du tri à bulles Pour chaque position, il faut parcourir en moyenne la moitié du tableau (au début tout le tableau, puis tout moins un élément, puis tout moins 2 éléments, puis ..., puis les 3 derniers éléments, puis les 2 dernières) Ce qui nous fait n parcours, avec pour chaque parcours n / 2 opérations : au total, n² / 2 opérations (un petit peu moins si l'algorithme s'arrête avant), soit une complexité O (n²)

Tri par comptage de fréquence int[] tab={2,5,5,7,9,2,3,2,0,9}; // on suppose les valeurs de tab dans 0..9 int[] freq= new int[10]; // valeurs de 0 à 9 Fréquences des valeurs de tab freq={1,0,3,1,0,2,0,1,0,2} Fréquences cumulées des valeurs de tab freq={1,1,4,5,5,7,7,8,8,10} Connaissant freq on peut trier tab en un seul passage !

Tri par comptage de fréquence void triComptage(int[] t, int k){ // t prend ses valeurs dans 0..k int[] f=new int[k+1]; int n=t.length ; int[] r=new int[n]; for(int i=0 ; i<k+1 ; i++) f[i]=0 ; // remplir f avec les frequences for(int j=0 ; j<n ; j++) f[t[j]]++ ; // remplir f avec les frequences cumulees for(int i=1 ; i<k+1 ; i++) f[i]=f[i] + f[i-1] ; // trier t dans r … }

Tri par comptage de fréquence void triComptage(int[] t, int k){ // t prend ses valeurs dans 0..k int[] f=new int[k+1]; int n=t.length ; int[] r=new int[n]; … // trier t dans r for (int j=n-1 ; j>=0 ; j--) { r[f[t[j]]-1]=t[j]; f[t[j]]-- ; } // recopier r dans t for(int j=0 ; j<n ; j++) t[j]=r[j] ;

Tri rapide (quicksort) Hoare (1962) 1. Choisir un élément pivot P T[0].. T[k-1] T[k] T[K+1]..T[N] 2. Partitionner le tableau autour du pivot P Tous les éléments avant P sont plus petits que P T[0]..T[k-1] <= P Tous les éléments après P sont plus grands que P P < T[K+1]..T[N] 3. Recommencer sur T[0]..T[k] sur T[K+1]..T[N]

Tri rapide (quicksort) Hoare (1962) 1. Choisir un élément pivot {4,3,9,1,0,5,6,3,8,2}; 2. Partitionner le tableau autour du pivot P {2,3,3,1,0,4,6,5,8,9} Tous les éléments avant P sont plus petits que P Tous les éléments après P sont plus grands que P

Partitionner autour du pivot int partition(int[] t, int g, int d){ int pivot = t[g], i = g, j = d ; while (i<j) { while(i<=d && t[i]<=pivot) i++; while(t[j]>pivot) j--; if (i<j) echanger(t,i,j); } // j est la position finale du pivot t[g] = t[j]; t[j] = pivot; return j;

Tri rapide La fonction partition() est itérative et sa complexité est en O(n) Testé sur trois tableaux de taille 1000 dont les éléments sont respectivement, générés aléatoirement, générés par ordre croissant, générés par ordre décroissant, le nombre d'échanges d'éléments observé est respectivement : 5477, 999, et 250 999 On montre que la complexité moyenne du tri rapide est en O(n.log(n)) Mais comme il n'y aucune raison pour que la partition décompose une table de longueur n en deux tables de longueur n/2, la complexité dans le pire des cas est très mauvaise, puisqu'elle est en n2

Cela existe déjà en Java ! void main(String[] args){ int[] tab={4,3,9,1,0,5,6,3,8,2,0}; afficherTableau(tab); // triRapide(tab,0,tab.length-1); java.util.Arrays.sort(tab); }