-
orestis.malaspin authoredorestis.malaspin authored
- Rappel (1/2)
- Quels algos avons-nous vu la semaine passée?
- Rappel (2/2)
- Algorithme du PPCM?
- Le calcul du PGCD (1/5)
- Définition
- Exemples:
- Mathématiquement
- Le calcul du PGCD (2/5)
- Algorithme
- Exemple d'algorithme
- Le calcul du PGCD (3/5)
- Transcrivez cet exemple en algorithme (groupe de 3) et codez-le (5-10min)!
- Optimisation
- Tentative de correction
- Le calcul du PGCD (4/5)
- Réusinage: l'algorithme d'Euclide
- Algorithme
- Le calcul du PGCD (5/5)
- Pseudo-code
- Le code du PGCD de 2 nombres
- Implémentez le pseudo-code et postez le code sur matrix (5min).
- Un corrigé possible
- Quelques algorithmes simples
- Collections: tableaux statiques
- Remarques
- Initialisation
- Recherche du minimum dans un tableau (1/2)
- Problématique
- Écrire un pseudo-code résolvant ce problème (groupe de 3), 2min
- Recherche du minimum dans un tableau (2/2)
- Implémenter ce bout de code en C (groupe de 3), 4min
- Tri par sélection (1/2)
- Problématique
- Idée d'algorithme
- Tri par sélection (2/2)
- Implémentation par groupe de 3
- Un type de tableau particulier
- Les chaînes de caractères
- Le type char{.C}
- Chaînes de caractères (strings)
- Exemple
- A quoi sert le \0?
- Syntaxe
- Fonctions
- Quels problèmes peuvent se produire avec strlen, strcpy, strcmp?
- Les anagrammes
- Définition
- Exemple
- Problème: Trouvez un algorithme pour déterminer si deux mots sont des anagrammes.
- Les anagrammes
- Il suffit de:
- Implémentation en live (offerte par HepiaVPN)
- Les palindromes
- Problème: proposer un algorithme pour détecter un palindrome
- Solution 1
- Solution 2
- Crible d'Ératosthène
- Exercice
- Pseudo-code
- Programme en C
title: "Introduction aux algorithmes"
date: "2022-10-05"
patat:
eval:
tai:
command: fish
fragment: false
replace: true
ccc:
command: fish
fragment: false
replace: true
images:
backend: auto
Rappel (1/2)
Quels algos avons-nous vu la semaine passée?
. . .
- L'algorithme de la factorielle.
- L'algorithme du PPCM.
- Le début de l'algorithme du PGCD.
Rappel (2/2)
Algorithme du PPCM?
. . .
int main() {
int m = 15, n = 12;
int mult_m = m, mult_n = n;
while (mult_m != mult_n) {
if (mult_m > mult_n) {
mult_n += n;
} else {
mult_m += m;
}
}
printf("Le ppcm de %d et %d est %d\n", n, m, mult_m);
}
Le calcul du PGCD (1/5)
Définition
Le plus grand commun diviseur (PGCD) de deux nombres entiers non nuls est le plus grand entier qui les divise en même temps.
Exemples:
PGCD(3, 4) = 1,
PGCD(4, 6) = 2,
PGCD(5, 15) = 5.
. . .
Mathématiquement
Décomposition en nombres premiers:
Le calcul du PGCD (2/5)
Algorithme
Par groupe de 3 (5-10min):
- réfléchissez à un algorithme alternatif donnant le PGCD de deux nombres;
- écrivez l'algorithme en pseudo-code.
. . .
Exemple d'algorithme
PGCD(36, 90):
90 % 36 != 0 // otherwise 36 would be PGCD
90 % 35 != 0 // otherwise 35 would be PGCD
90 % 34 != 0 // otherwise 34 would be PGCD
...
90 % 19 != 0 // otherwise 19 would be PGCD
90 % 18 == 0 // The end!
- 18 modulos, 18 assignations, et 18 comparaisons.
Le calcul du PGCD (3/5)
Transcrivez cet exemple en algorithme (groupe de 3) et codez-le (5-10min)!
. . .
Optimisation
- Combien d'additions / comparaisons au pire?
- Un moyen de le rendre plus efficace?
. . .
Tentative de correction
void main() {
int n = 90, m = 78;
int gcd = 1;
for (int div = n; div >= 2; div--) { // div = m, sqrt(n)
if (n % div == 0 && m % div == 0) {
gcd = div;
break;
}
}
printf("Le pgcd de %d et %d est %d\n", n, m, gcd);
}
Le calcul du PGCD (4/5)
Réusinage: l'algorithme d'Euclide
Dividende = Diviseur * Quotient + Reste
PGCD(35, 60):
35 = 60 * 0 + 35 // 60 -> 35, 35 -> 60
60 = 35 * 1 + 25 // 35 -> 60, 25 -> 35
35 = 25 * 1 + 10 // 25 -> 35, 20 -> 25
25 = 10 * 2 + 5 // 10 -> 25, 5 -> 10
10 = 5 * 2 + 0 // PGCD = 5!
. . .
Algorithme
Par groupe de 3 (5-10min):
- analysez l'exemple ci-dessus;
- transcrivez le en pseudo-code.
Le calcul du PGCD (5/5)
Pseudo-code
entier pgcd(m, n) {
tmp_n = n
tmp_m = m
tant que (tmp_m ne divise pas tmp_n) {
tmp = tmp_n
tmp_n = tmp_m
tmp_m = tmp modulo tmp_m
}
retourne tmp_m
}
Le code du PGCD de 2 nombres
Implémentez le pseudo-code et postez le code sur matrix (5min).
. . .
Un corrigé possible
#include <stdio.h>
void main() {
int n = 90;
int m = 78;
printf("n = %d et m = %d\n", n, m);
int tmp_n = n;
int tmp_m = m;
while (tmp_n%tmp_m > 0) {
int tmp = tmp_n;
tmp_n = tmp_m;
tmp_m = tmp % tmp_m;
}
printf("Le pgcd de %d et %d est %d\n", n, m, tmp_m);
}
Quelques algorithmes simples
- Remplissage d'un tableau et recherche de la valeur minimal
- Anagrammes
- Palindromes
- Crible d'ératosthène
. . .
- Ces algorithme nécessitent d'utiliser des tableaux.
Collections: tableaux statiques
-
Objets de même type: leur nombre est connu à la compilation;
-
Stockés contigüement en mémoire (très efficace);
#define SIZE 10 int entiers[] = {2, 1, 4, 5, 7}; // taille 5, initialisé int tab[3]; // taille 3, non initialisé float many_floats[SIZE]; // taille 10, non initialisé
-
Les indices sont numérotés de
0
àtaille-1
;int premier = entier[0]; // premier = 2 int dernier = entier[4]; // dernier = 7
-
Les tableaux sont non-initialisés par défaut;
-
Les bornes ne sont jamais vérifiées.
int indetermine_1 = tab[1]; // undefined behavior int indetermine_2 = entiers[5]; // UB
Remarques
-
Depuis
C99
possibilité d'avoir des tableaux dont la taille est inconnue à la compilation;int size; scanf("%d", &size); char string[size];
. . .
- Considéré comme une mauvaise pratique: que se passe-t-il si
size == 1e9
? - On préfère utiliser l'allocation dynamique de mémoire pour ce genre de cas-là (spoiler du futur du cours).
Initialisation
-
Les variables ne sont jamais initialisées en
C
par défaut. -
Question: Que contient le tableau suivant?
double tab[4];
. . .
- Réponse: On en sait absolument rien!
- Comment initialiser un tableau?
. . .
#define SIZE 10
double tab[SIZE];
for (int i = 0; i < SIZE; ++i) {
tab[i] = rand() / (double)RAND_MAX * 10.0 - 5.0;
// tab[i] contient un double dans [-5;5]
}
Recherche du minimum dans un tableau (1/2)
Problématique
Trouver la valeur minimale contenue dans un tableau et l'indice de l'élément le plus petit.
Écrire un pseudo-code résolvant ce problème (groupe de 3), 2min
. . .
index = 0
min = tab[0]
for i in [1; SIZE] {
if min > tab[i] {
min = tab[i]
index = i
}
}
Recherche du minimum dans un tableau (2/2)
Implémenter ce bout de code en C (groupe de 3), 4min
. . .
int index = 0;
float min = tab[0];
for (int i = 1; i < SIZE; ++i) {
if min > tab[i] {
min = tab[i];
index = i;
}
}
Tri par sélection (1/2)
Problématique
Trier un tableau par ordre croissant.
Idée d'algorithme
ind = 0
tant que (ind < SIZE-1)
Trouver le minimum du tableau, tab_min[ind:SIZE].
Échanger tab_min avec tab[ind]
ind += 1
Tri par sélection (2/2)
Implémentation par groupe de 3
- Initialiser aléatoirement un tableau de
double
de taille 10; - Afficher le tableau;
- Trier par sélection le tableau;
- Afficher le résultat trié;
- Vérifier algorithmiquement que le résultat est bien trié.
Un type de tableau particulier
Les chaînes de caractères
string = tableau + char + magie noire
char
{.C}
Le type - Le type
char
{.C} est utilisé pour représenter un caractère. - C'est un entier 8 bits signé.
- En particulier:
-
Écrire
char c = 'A';
-
Est équivalent à:
char c = 65;
-
- Les fonctions d'affichage interprètent le nombre comme sa valeur ASCII.
Chaînes de caractères (strings)
- Chaîne de caractère
==
tableau de caractères terminé par la valeur'\0'
{.C} ou0
{.C}.
Exemple
char *str = "HELLO !";
char str[] = "HELLO !";
Est représenté par
char |
H |
E |
L |
L |
O |
! |
\0 |
|
---|---|---|---|---|---|---|---|---|
ASCII |
72 |
69 |
76 |
76 |
79 |
32 |
33 |
0 |
. . .
\0
?
A quoi sert le . . .
Permet de connaître la fin de la chaîne de caractères (pas le cas des autres sortes de tableaux).
Syntaxe
char name[5];
name[0] = 'P'; // = 70;
name[1] = 'a'; // = 97;
name[2] = 'u'; // = 117;
name[3] = 'l'; // = 108;
name[4] = '\0'; // = 0;
char name[] = {'P', 'a', 'u', 'l', '\0'};
char name[5] = "Paul";
char name[] = "Paul";
char name[100] = "Paul is not 100 characters long.";
Fonctions
-
Il existe une grande quantités de fonction pour la manipulation de chaînes de caractères dans
string.h
. -
Fonctions principales:
// longueur de la chaîne (sans le \0) size_t strlen(char *str); // copie jusqu'à un \0 char *strcpy(char *dest, const char *src); // copie len char char *strncpy(char *dest, const char *src, size_t len); // compare len chars int strncmp(char *str1, char *str2, size_t len); // compare jusqu'à un \0 int strcmp(char *str1, char *str2);
-
Pour avoir la liste complète:
man string
.
. . .
strlen
, strcpy
, strcmp
?
Quels problèmes peuvent se produire avec Les anagrammes
Définition
Deux mots sont des anagrammes l'un de l'autre quand ils contiennent les mêmes lettres mais dans un ordre différent.
Exemple
t |
u |
t |
u |
t |
\0 |
|
|
---|---|---|---|---|---|---|---|
t |
u |
t |
t |
u |
\0 |
|
|
Problème: Trouvez un algorithme pour déterminer si deux mots sont des anagrammes.
Les anagrammes
Il suffit de:
- Trier les deux mots.
- Vérifier s'ils contiennent les mêmes lettres.
Implémentation en live (offerte par HepiaVPN)
int main() { // pseudo C
tri(mot1);
tri(mot2);
if egalite(mot1, mot2) {
// anagrammes
} else {
// pas anagrammes
}
}
Les palindromes
Mot qui se lit pareil de droite à gauche que de gauche à droite:
. . .
- rotor, kayak, ressasser, ...
Problème: proposer un algorithme pour détecter un palindrome
. . .
Solution 1
while (first_index < last_index {
if (mot[first_index] != mot [last_index]) {
return false;
}
first_index += 1;
last_index -= 1;
}
return true;
. . .
Solution 2
mot_tmp = revert(mot);
return mot == mot_tmp;
Crible d'Ératosthène
Algorithme de génération de nombres premiers.
Exercice
- À l'aide d'un tableau de booléens,
- Générer les nombres premiers plus petits qu'un nombre
Pseudo-code
- Par groupe de trois, réfléchir à un algorithme.
Programme en C
- Implémenter l'algorithme et le poster sur le salon
Element
.