690 likes | 830 Views
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. // déclaration char[] t ;
E N D
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 // déclaration 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(”? ”); } for(int i=0 ; i< t.length ; i++){ t[i]=t[i]+1; } for(int i=0 ; i< t.length ; i++){ 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 // déclaration 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(”? ”); } }
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
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])); } }
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+bx2y2 = 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; // obtenir une valeur dans l'intervalle [0..25] 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}; int[] t2; t2 = t1; S.o.p("Tableaux "+t1+","+t2); }
Affection de tableaux void main(String[] args){ int[] t1 = {5, 2, 6}; int[] t2; t2 = t1; 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 : 39 6 1 2 insérons 9 : 3 96 1 2 insérons 6 : 3 6 91 2 insérons 1 : 1 3 6 92 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); afficherTableau(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 36 9 plus petit est 6 : 1 2 3 69