Skip to content
Snippets Groups Projects
Verified Commit bf4583cd authored by orestis.malaspin's avatar orestis.malaspin
Browse files
parents e5ccf77f 73ac79cc
No related branches found
No related tags found
No related merge requests found
Pipeline #14738 passed
Showing
with 882 additions and 0 deletions
File moved
# Algorithmes et structures de données 2020-21
Contenu du cours 2 du du 23.09.2020
*****
## Plus petit commun multiple (PPCM) de deux nombres
- Algorithme de PPCM: exemple avec 12 et 15
| Tester si| `>, <` ou `=`| |
|-----------|:------------:|:---------|
| | `12 < 15` | |
| | `24 > 15` | |
| | `24 < 30` | |
| | `36 > 30` | |
| | `36 < 45` | |
| | `48 > 45` | |
| | `48 < 60` | |
| | `60 = 60` | **Fin !**|
## Plus grand diviseur commun (PGCD) de deux nombres
- Algorithme naïf du PGCD
- Pseudo-code du calcul du `PGCD` de `N` et `M`
```
si M rem N = 0 alors
PGCD := N
sinon
pour I de sqrt(N) à 1 faire
si N rem I = 0 et M rem I = 0 alors
PGCD := I
exit
fin si
fin pour
fin si
```
- Algorithme d'Euclide : exemple avec N = 35 et M = 60
| Dividende | = | Diviseur \* Quotient | + | Reste |
|:----------:|:----:|:---------------------:|:---:|:-------:|
| 35 | = | 60 \* 0 | + | 35 |
| 60 | = | 35 \* 1 | + | 25 |
| 35 | = | 25 \* 1 | + | 10 |
| 25 | = | 10 \* 2 | + | 5 |
| 10 | = | 5 \* 2 | + | 0 |
> > => PGCD = 5
## Exercice : Montrer que `PGCD(M,N)*PPCM(M,N) = M*N`
- Utiliser la décomposition en facteurs 1<sup>er<sup/>
## Type composé : tableaux statiques à une dimension
- Collection ordonnée d'objets de même type dont le nombre est connu à la compilation
- La taille d'un tableau statique ne peut pas changer en cours d'exécution
- Allocation contiguë en mémoire et sur la pile
```C
int entiers[] = {1,2,3,4,5};
int tab[3];
```
- Accès aux éléments d’un tableau via l’opérateur `[index]``index` est l’indice de l’élément à accéder, `index` va de 0 à la taille du tableau moins un
```C
int premier = entiers[0];
int dernier = entiers[4];
```
> **Attention!** L'accès à un indice hors de l'intervalle zéro à la taille du tableau moins un ne produit pas d'erreur à la compilation, mais possible à l'exécution.
- Tableau de nombres flottants
```C
const int SIZE = 13;
float tab[SIZE];
```
- Initialisation d'un tableau de floats avec `i*i`, puis avec des nombres aléatoires
```C
for (int i=0;i<SIZE;i++) {
tab[i] = (float)rand()/(float)(RAND_MAX) ;
}
```
- Recherche d'un indice de la valeur minimale d'un tableau de floats et permutation avec l'élément en 1<sup>ère</sup> position
- Répétition de l'opération précédente sur des tranches du tableau
- Tri par sélection avec illustration sur un exemple
- Algorithme de vérification que deux mots sont des anagrammes en utilisant un tri
# Algorithmes et structures de données 2020-21
Contenu du cours 3 du 30.09.2020
*****
## Tableaux à deux dimensions
- Image noir et blanc avec des booléens : initialisation
```C
int n = 8, m = 8;
bool image_nb[n][m];
for (int i=0;i<n;i++) {
for (int j=0;j<m;j++) {
image_nb[i][j] = true;
}
}
```
- Image en niveaux de gris : initialisation
```C
int n = 8, m = 8;
int image_gris[n][m];
for (int i=0;i<n;i++) {
for (int j=0;j<m;j++) {
image_gris[i][j] = rand()%256;
}
}
```
>
* Négatif d'une image à 256 niveaux de gris
- Appliquer à chaque pixel l'opération `pixel = 255 - pixel`
```C
for (int i=0;i<n;i++) {
for (int j=0;j<m;j++) {
image_gris[i][j] = 255 - ­image_gris[i][j];
}
}
```
## Type énuméré
- On définit un type énuméré `semaine, coin, mois, couleur, direction` en énumérant toutes ses valeurs possibles.
Explicitement
```C
enum semaine {lu,ma,me,je,ve,sa,di};
enum coin {cinq_cts=5,dix_cts=10,vingt_cts=20,euro=100};
enum mois {
jan=1,feb,mar,apr,mai,jun,jul,aug,sep,oct,nov,dec
};
enum couleur {RED,GREEN,BLUE};
enum direction {EST=2,OUEST=3,NORD=0,SUD=1};
```
> Les valeurs d’un type énuméré peuvent être considérées comme des entiers.
Sans précision particulière, le premier élément correspond à 0 et les suivants à 1, 2, etc.
Sinon on peut explicitement spécifier des valeurs.
Rien n’empêche d'attribuer plusieurs fois le même nombre.
## Opérateur de contrôle `switch`
- Comparaison entre une valeur et un ensemble de choix pour sélectionner une action à effectuer. Toutes les possibilités doivent être prises en compte.
```C
void main() {
type data = id1;
int val;
switch(data) {
case ID1: val = data+1; break;
case ID2: val = data*2; break;
case ID3: val = data/3.0; break;
};
println!(\"val =%d\\n\",val);
}
```
## Exemple de la « couverture de la reine »
```C
enum piece {SAFE,VULN,QUEEN};
int size = 8;
piece board[size][size];
// initialisation de l'échiquier
for (int i=0;i<size;i++) {
for (int j=0;j<size;j++) {
board[i][j] = SAFE;
}
}
int pos_reine[] = {3,4};
// couverture sans les diagonales !!!
for (int k=0;k<size;k++) {
board[k][pos_reine[1]] = VULN;
board[pos_reine[0]][k] = VULN;
}
board[pos_reine[0]][pos_reine[1]] = QUEEN;
```
## Matrices
1. Tableau 2D de nombres
2. Opérations arithmétiques
1. Addition : `C = A+B`
2. Soustraction : `C = A-B`
3. Multiplication : `C = A*B` (produit lignes/colonnes)
4. Puissance entière : `C = A`<sup>n</sup>
#include <stdio.h>
// Programme calculant la factorielle d'un nombre
void main() {
int nb = 1;
printf("Entrer un nombre: ");
scanf("%d",&nb);
int fact = 1;
for(int i=2;i<=nb;i++) {
fact *= i;
}
/*int iter = 2;
while(iter <= nb) {
fact *= iter;
iter++;
}
do {
fact *= iter;
iter++;
} while(iter <= nb);*/
printf("Fact = %d\n",fact);
}
File moved
#include <stdio.h>
// calcul du PGCD de deux nombres
void main() {
int n = 90;
int m = 78;
printf("n = %d et m = %d\n",n,m);
// algorithme naif
int gcd = 1;
for (int div=n;div>=2;div--) {
if (n%div == 0 && m%div == 0) {
gcd = div;
break;
}
}
printf("Le pgcd de %d et %d est %d\n",n,m,gcd);
// algorithme d'Euclide
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);
}
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
// Programme calculant le plus petit commun multiple (PPCM) de deux nombres
void main() {
int n = 15,m = 12;
int res = n*m;
for (int i=2;i<=m;i++) {
if (n*i%m == 0) {
res = n*i;
break;
}
}
printf("Le ppcm de %d et %d est %d\n",n,m,res);
int i = 1;
while (n*i%m != 0) {
i++;
}
printf("Le ppcm de %d et %d est %d\n",n,m,n*i);
}
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
void main() {
int n = 15,m = 12;
printf("Entrez n et m:\n");
scanf("%d %d",&n,&m);
int tmp_n = n,tmp_m = m;
/*
while (tmp_n != tmp_m) {
if (tmp_n < tmp_m) {
tmp_n += n;
} else {
tmp_m += m;
}
}
while (true) {
if (tmp_n < tmp_m) {
tmp_n += n;
} else if (tmp_n > tmp_m) {
tmp_m += m;
} else {
break;
}
}
*/
do {
if (tmp_n < tmp_m) {
tmp_n += n;
} else {
tmp_m += m;
}
} while (tmp_n != tmp_m);
printf("Le ppcm de %d et %d est %d\n",n,m,tmp_m);
}
File added
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
bool anagramme_1(char mot1[],char mot2[]);
bool anagramme_2(char mot1[],char mot2[]);
void sort(char mot[]);
void main() {
char mot1[30];
char mot2[30];
printf("Entrez deux mots:\n");
scanf("%s%s",mot1,mot2);
printf("Les mots %s et %s",mot1,mot2);
if (anagramme_1(mot1,mot2)) {
printf(" sont des anagrammes\n");
} else {
printf(" ne sont pas des anagrammes\n");
}
}
bool anagramme_1(char mot1[],char mot2[]) {
sort(mot1);
sort(mot2);
return (strcmp(mot1,mot2) == 0);
}
bool anagramme_2(char mot1[],char mot2[]) {
int lg1 = strlen(mot1), lg2 = strlen(mot2);
bool egal = true;
if (lg1 == lg2) {
for (int i=0;i<lg1;i++) {
if (mot1[i] != mot2[i]) {
egal = false;
break;
}
}
} else {
egal = false;
}
return egal;
}
int index_min(char mot[],int i) {
int ind_min = i;
for (int k=i+1;k<strlen(mot);k++) {
if (mot[k] < mot[ind_min]) {
ind_min = k;
}
}
return ind_min;
}
void permut(char mot[],int i,int j) {
char tmp = mot[i];
mot[i] = mot[j];
mot[j] = tmp;
}
void sort(char mot[]) {
int lg = strlen(mot);
for (int i=0;i<lg-1;i++) {
int ind_min = index_min(mot,i);
char tmp = mot[i];
mot[i] = mot[ind_min];
mot[ind_min] = tmp;
}
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// remplissage d'un tableau avec des nombres aléatoires
void random_init(int n,int tab[n]) {
for (int i=0;i<n;i++) {
tab[i] = rand()%100;
}
printf("\n");
}
// remplissage d'un tableau avec le carré de l'index
void square_init(int n,int tab[n]) {
for (int i=0;i<n;i++) {
tab[i] = i*i;
}
}
// recherche de l'indice de la valeur min dans un tableau
int index_min(int n,int tab[n]) {
int ind_min = 0;
for (int i=1;i<n;i++) {
if (tab[i] < tab[ind_min]) {
ind_min = i;
}
}
return ind_min;
}
void print(int n,int tab[n]) {
for (int i=0;i<n;i++) {
printf("%d ",tab[i]);
}
printf("\n");
}
void main() {
srand(time(NULL));
int size;
printf("size = ");
scanf("%d",&size);
int tab[size];
square_init(size,tab);
print(size,tab);
random_init(size,tab);
print(size,tab);
int ind_min = index_min(size,tab);
printf("Tab: index du min = %d / valeur min = %d de tab\n",ind_min,tab[ind_min]);
}
#include <stdio.h>
#include <stdlib.h>
typedef enum _piece {SAFE, VULN, QUEEN} piece;
void print(int n,int m,piece tab[n][m]);
void init(int n,int m,piece tab[n][m],piece pce);
void couverture(int n,int m,piece tab[n][m],int r_x,int r_y);
void main() {
int n=8;
piece board[n][n];
init(n,n,board,SAFE);
print(n,n,board);
printf("Entrez la colonne de la reine (1..%d): ",n);
int r_j;
scanf("%d",&r_j);
r_j--;
printf("Entrez la ligne de la reine ('a'..'%c'): ",n-1+'a');
char ch[1];
scanf("%s",ch);
couverture(n,n,board,ch[0]-'a',r_j);
print(n,n,board);
}
void print(int n,int m,piece board[n][m]) {
for (int i=n-1;i>=0;i--) {
printf("%c ",'a'+i);
for (int j=0;j<m;j++) {
switch(board[i][j]) {
case VULN: printf(" *"); break;
case SAFE : printf(" o"); break;
case QUEEN: printf(" R");
}
}
printf("\n");
}
printf("\n ");
for (int j=0;j<m;j++) {
printf(" %d",j+1);
}
printf("\n");
}
void couverture(int n,int m,piece board[n][m],int r_i,int r_j) {
for (int k=0;k<n;k++) {
board[k][r_j] = VULN; //colonne de la reine
}
for (int k=0;k<m;k++) {
board[r_i][k] = VULN; //ligne de la reine
int tmp = r_j-k;
if (0 <= r_i+tmp && r_i+tmp < n) { //diagonale montante
board[r_i+tmp][k] = VULN;
}
if (0 <= r_i-tmp && r_i-tmp < n) { //diagonale descendante
board[r_i-tmp][k] = VULN;
}
}
board[r_i][r_j] = QUEEN;
}
void init(int n,int m,piece tab[n][m],piece pce) {
for (int i=0;i<n;i++) {
for (int j=0;j<m;j++) {
tab[i][j] = pce;
}
}
}
#include <stdio.h>
#include <stdlib.h>
typedef enum _piece {SAFE, VULN, QUEEN} piece;
void print(int n,int m,cell tab[n][m]);
void init_board(int n,int m,cell tab[n][m]);
void couverture(int n,int m,cell tab[n][m],int r_x,int r_y);
void main() {
int n=8;
piece board[n][n];
init(n,n,board,SAFE);
print(n,n,board);
printf("Entrez la colonne de la reine (1..%d): ",n);
int r_j;
scanf("%d",&r_j);
r_j--;
printf("Entrez la ligne de la reine ('a'..'%c'): ",n-1+'a');
char ch[1];
scanf("%s",ch);
couverture(n,n,board,ch[0]-'a',r_j);
print(n,n,board);
}
void print(int n,int m,piece board[n][m]) {
for (int i=n-1;i>=0;i--) {
printf("%c ",'a'+i);
for (int j=0;j<m;j++) {
switch(board[i][j]) {
case VULN: printf(" *"); break;
case SAFE : printf(" o"); break;
case QUEEN: printf(" R");
}
}
printf("\n");
}
printf("\n ");
for (int j=0;j<m;j++) {
printf(" %d",j+1);
}
printf("\n");
}
void couverture(int n,int m,piece board[n][m],int r_i,int r_j) {
//colonne de la reine
for (int k=0;k<n;k++) {
board[k][r_j] = VULN;
}
//ligne de la reine
for (int k=0;k<m;k++) {
board[r_i][k] = VULN;
}
//diagonale montante
for (int k=0;r_i+k<n && r_j+k<m;k++) {
board[r_i+k][r_j+k] = VULN;
}
//compléter les autres diagonales
board[r_i][r_j] = QUEEN;
}
void init(int n,int m,piece tab[n][m],piece pce) {
// à compléter
}
#include <stdio.h>
#include <stdbool.h>
void init(int n,bool tab[n],bool val);
void tracer_multiples(int n,bool tab[n],int i);
void garder_nb1er(int n,bool tab[n]);
void print_nb1er(int n,bool tab[n]);
void main() {
int size;
printf("size = ");
scanf("%d",&size);
bool tab[size];
init(size,tab,true);
garder_nb1er(size,tab);
printf("Nombres 1er < %d:",size);
print_nb1er(size,tab);
}
void init(int n,bool tab[n],bool val) {
for (int i=0;i<n;i++) {
tab[i] = true;
}
}
void tracer_multiples(int n,bool tab[n],int i) {
int j = i;
while (true) {
j += i;
if (j >= n) {
break;
}
if (tab[j]) {
tab[j] = false;
}
}
}
void garder_nb1er(int n,bool tab[n]) {
for (int i=2;i<n;i++) {
if (tab[i]) {
tracer_multiples(n,tab,i);
}
}
}
void print_nb1er(int n,bool tab[n]) {
for (int i=2;i<n;i++) {
if (tab[i]) {
printf("%d ",i);
}
}
printf("\n");
}
#include <stdio.h>
// fonction calculant la factorielle d'un nombre
int factorielle(int n);
void main() {
int nb = 1;
printf("Entrer un nombre: ");
scanf("%d",&nb);
printf("Fact = %d\n",factorielle(nb));
}
int factorielle(int n) {
int facto = 1;
for(int i=2;i<=n;i++) {
facto *= i;
}
return facto;
}
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
// fonction testant si un nombre est 1er
bool is_prime(int nb);
void main() {
int nb = 1;
printf("Entrez un nombre: ");
scanf("%d",&nb);
if (is_prime(nb)) {
printf("Le nombre %d est premier\n",nb);
} else {
printf("Le nombre %d n'est pas premier\n",nb);
}
}
bool is_prime(int nb) {
bool premier = true;
for (int div=2;div<=sqrt(nb);div++) {
if (nb%div == 0) {
premier = false;
break;
}
}
return premier;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
bool is_palindrome_1(char mot[]);
bool is_palindrome_2(char mot[]);
void main() {
printf("Entrez une chaîne de caractères: ");
char mot[30];
scanf("%s",mot);
printf("Le mot %s",mot);
if (is_palindrome_1(mot)) {
printf(" est un palindrome\n");
} else {
printf(" n'est pas un palindrome\n");
}
}
bool is_palindrome_1(char mot[]) {
int lg = strlen(mot);
bool palindrome = true;
int first_idx = 0, last_idx = lg-1;
while (first_idx < last_idx) {
if (mot[first_idx] != mot[last_idx]) {
palindrome = false;
break;
}
first_idx += 1;
last_idx -= 1;
}
return palindrome;
}
bool is_palindrome_2(char mot[]) {
int lg = strlen(mot);
char inverse[lg+1];
for (int i=0;i<lg;i++) {
inverse[i] = mot[lg-1+i];
}
inverse[lg] = '\0';
return (strcmp(inverse,mot) == 0);
}
#include <stdio.h>
// calcul du PGCD de deux nombres: algorithme naif
int pgcd_naif(int n, int m);
// calcul du PGCD de deux nombres: algorithme d'Euclide
int pgcd_euclide(int n, int m);
void main() {
int n,m;
printf("n = ");
scanf("%d",&n);
printf("m = ");
scanf("%d",&m);
printf("Le pgcd de %d et %d est %d\n",n,m,pgcd_naif(n,m));
printf("Le pgcd de %d et %d est %d\n",n,m,pgcd_euclide(n,m));
}
// algorithme naif
int pgcd_naif(int n, int m) {
int gcd = 1;
for (int div=n;div>=2;div--) {
if (n%div == 0 && m%div == 0) {
gcd = div;
break;
}
}
return gcd;
}
// algorithme d'Euclide
int pgcd_euclide(int n, int 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;
}
return tmp_m;
}
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
// fonctions calculant le plus petit commun multiple (PPCM) de deux nombres
int ppcm_1(int n,int m);
int ppcm_2(int n,int m);
void main() {
int n,m;
printf("n = ");
scanf("%d",&n);
printf("m = ");
scanf("%d",&m);
printf("Le ppcm de %d et %d est %d\n",n,m,ppcm_1(n,m));
printf("Le ppcm de %d et %d est %d\n",n,m,ppcm_2(n,m));
}
int ppcm_1(int n,int m) {
int res = n*m;
for (int i=2;i<=m;i++) {
if (n*i%m == 0) {
res = n*i;
break;
}
}
}
int ppcm_2(int n,int m) {
int fact = 1;
while (n*fact%m != 0) {
fact++;
}
return fact*n;
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
void print(int n,double tab[n]);
void random_init(int n,double tab[n]);
void tri_selection(int n,double tab[n]);
bool croissant(int n,double tab[n]);
int main() {
srand(time(NULL));
int n;
printf("n=");
scanf("%d",&n);
double res[n];
random_init(n,res);
print(n,res);
tri_selection(n,res);
print(n,res);
if (!croissant(n,res)) {
return EXIT_FAILURE;
}
printf("sorted\n");
return EXIT_SUCCESS;
}
void print(int n,double tab[n]) {
for (int i=0;i<n;i++) {
printf("%.2lf ",tab[i]);
}
printf("\n");
}
void random_init(int n,double tab[n]) {
for (int i=0;i<n;i++) {
tab[i] = 100.0*rand()/(double)RAND_MAX;
}
}
int index_min(int n,double tab[n],int i) {
int ind_min = i;
for (int k=i+1;k<n;k++) {
if (tab[k] < tab[ind_min]) {
ind_min = k;
}
}
return ind_min;
}
void permut(int n,double tab[n],int i,int j) {
double tmp = tab[i];
tab[i] = tab[j];
tab[j] = tmp;
}
void tri_selection(int n,double tab[n]) {
for (int i=0;i<n-1;i++) {
int ind_min = index_min(n,tab,i);
if (tab[i] != tab[ind_min]) {
permut(n,tab,i,ind_min);
}
}
}
bool croissant(int n,double tab[n]) {
for (int i=0;i<n-1;i++) {
if (tab[i] > tab[i + 1]) {
return false;
}
}
return true;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment