Post

TD3 Tableaux dynamique Correction Informatique2 PREING1 S2

Télécharger le TD3 Tableaux dynamique en pdf

Exercices : 1 2 3 4 5

Exercice 1

exercice 1

lineabcpapbppa*pa*pb*ppa**paa
9???adresse de a??????
10???adresse de aadresse de b?????
11???adresse de aadresse de badresse de pa??pa = adresse de a?
1210??adresse de aadresse de badresse de pa10?pa = adresse de a10
1310-2?adresse de aadresse de badresse de pa10-2pa = adresse de a10
1410-2-4adresse de aadresse de badresse de pa10-2pa = adresse de a10
153-2-4adresse de aadresse de badresse de pa3-2pa = adresse de a3
163-2-4adresse de cadresse de badresse de pa-4-2pa = adresse de c-4
173-21adresse de cadresse de badresse de pa1-2pa = adresse de c1

Exercice 2

exercice 2

  • On importe tout d’abord toute les librairies utiles, on créer une fonction qui génère un nombre aléatoire et une procédure qui permet d’afficher les Tableaux
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// générer un entier aléatoire entre x et y inclu
int randomInt(int x, int y) {
    return rand() % (y - x + 1) + x;
}

// afficher un tableau d'entiers
void afficherTab(int* tableau, int n) {
    printf("[");
    for (int i = 0; i < n; i++) {
        printf("%d", tableau[i]);
        if (i < n - 1) {
            printf(", ");
        }
    }
    printf("]\n");
}
  • On crée deux fonction sécurisée pour le scanf, une pour les nombre et une pour les nombre positifs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int better_scan(char * message){
    int ret_var = 0;
    int value = 1;
    while (ret_var != 1)
    {   
        printf(message);
        ret_var = scanf("%d", &value);
        while(getchar()!='\n'){} // Ligne facultative de sécurisation
    }
    return value;
    
}
int better_scan_pos(char * message){
    int ret_var = 0;
    int value = 1;
    while (ret_var != 1 || value < 0)
    {   
        printf(message);
        ret_var = scanf("%d", &value);
        while(getchar()!='\n'){} // Ligne facultative de sécurisation
    }
    return value;
    
}

Ces fonctions sont facultatives, les lignes while(getchar()!='\n'){} permetent de vider le buffer et d’avoir des scanf qui ne bouclent pas a l’infinie lors d’une mauvaise saisie.

  • On crée maintenant la fonction qui crée un tableau d’entiers aléatoires entre x et y
1
2
3
4
5
6
7
8
9
10
11
12
int* randTab(int n, int x, int y) {
    int* tableau = (int*)malloc(n * sizeof(int)); //allocation de la mémoire 
    if (tableau == NULL) {
        printf("Erreur d'allocation de mémoire.\n");
        exit(EXIT_FAILURE);
    }
    for (int i = 0; i < n; i++) {
        tableau[i] = randomInt(x, y);
    }
    return tableau;
}

EXIT_FAILURE est définie dans stdlib et permettent une meilleur lecture du code, , exit() permet de sortir du programme avec un code d’erreur.

  • On créer mainteant la fonction qui pemet de filtrer les valeurs pair du tableau
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int* tabPair(int* tableau, int n, int *nbpaire_ptr) {
    int nbPairs = 0;
    // Compte le nombre de valeurs paires dans le tableau
    for (int i = 0; i < n; i++) {
        if (tableau[i] % 2 == 0) {
            nbPairs++;
        }
    }
    *nbpaire_ptr = nbPairs; // Stocke le nombre de valeurs paires
    int* tableauPairs = (int*)malloc(nbPairs * sizeof(int));
    if (tableauPairs == NULL) {
        printf("Erreur d'allocation de mémoire.\n");
        exit(EXIT_FAILURE);
    }

    int index = 0;
    // Remplit le tableau avec les valeurs paires
    for (int i = 0; i < n; i++) {
        if (tableau[i] % 2 == 0) {
            tableauPairs[index] = tableau[i];
            index++;
        }
    }
    return tableauPairs;
}
  • On écrit maintenant la fonction qui permet de supprimer les valeurs identiques côtes a côtes l’une de l’autre
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int* noDouble(int* tableau, int n, int *nbdoublon) {
    int* tableauSansDoublons = (int*)malloc(n * sizeof(int));
    if (tableauSansDoublons == NULL) {
        printf("Erreur d'allocation de mémoire.\n");
        exit(EXIT_FAILURE);
    }
    int index = 0;
    tableauSansDoublons[index] = tableau[0]; // Première valeur toujours conservée
    index++;
    // Parcourt le tableau pour supprimer les doublons contigus
    for (int i = 1; i < n; i++) {
        if (tableau[i] != tableau[i - 1]) { // Si la valeur actuelle est différente de la précédente
            tableauSansDoublons[index] = tableau[i]; // On la conserve dans le nouveau tableau
            index++;
        }
    }
    *nbdoublon = index - 1; // Stocke le nombre de valeurs uniques
    return realloc(tableauSansDoublons, index * sizeof(int)); // Redimensionne le tableau
}

EXIT_FAILURE est définie dans stdlib et permettent une meilleur lecture du code

  • On peut mainteant tester le tout dans le main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
int main() {
    srand(time(NULL));
    int n, x, y;

    n = better_scan_pos("Entrez la taille du tableau : ");
    x = better_scan("Entrez la borne inférieure (x) : ");
    y = better_scan("Entrez la borne supérieure (y) : ");

    
    // Génère un tableau aléatoire et l'affiche
    int* tableau = randTab(n, x, y);
    printf("Tableau original : ");
    afficherTab(tableau, n);

    int nombre_de_paire;
    int* tableauPairs = tabPair(tableau, n, &nombre_de_paire);
    printf("Tableau des valeurs paires : ");
    afficherTab(tableauPairs, nombre_de_paire);

    int nombre_de_doublon;
    int* tableauSansDoublons = noDouble(tableau, n, &nombre_de_doublon);
    printf("Tableau sans doublons contigus : ");
    afficherTab(tableauSansDoublons, nombre_de_doublon);

    // On oublie pas de libérer la mémoire meme si dans ce cas ce n'est pas important
    free(tableau);
    free(tableauPairs);
    free(tableauSansDoublons);

    return 0;
}

Exercice 3

exercice 3 exercice 3_2

  • On importe tout d’abord toute les librairies utiles et on crée une procédure qui permet d’afficher les prénoms
1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void AfficherPrenom(char **tabPrenom, int nbPrenoms){
    printf("\nPrénoms stockés :\n");
    for (int i = 0; i < nbPrenoms; i++) {
        printf("%s\n", tabPrenom[i]);
    }
}
  • On réutilise notre fonction de scanf sécurisé
1
2
3
4
5
6
7
8
9
10
11
12
int better_scan_pos(char * message){
    int ret_var = 0;
    int value = 1;
    while (ret_var != 1 || value < 0)
    {   
        printf(message);
        ret_var = scanf("%d", &value);
        while(getchar()!='\n'){} // Ligne facultative de sécurisation
    }
    return value;
    
}

Cette fonction est facultative, la ligne while(getchar()!='\n'){} permet de vider le buffer et d’avoir un scanf qui ne boucle pas a l’infinie lors d’une mauvaise saisie.

  • On crée la procédure qui permet de mettre la première lettre de chaque prénom en majuscules
1
2
3
4
5
void Maj(char* prenom) {
    if (prenom[0]>=65 && prenom[0]<=90) {
        prenom[0] += 32; // Met la première lettre en majuscule
    }
}
  • Il existe une autre méthode pour y parvenir on peut utiliser les fonction de la bibliothèque ctype.h
1
2
3
4
5
void Maj(char* prenom) {
    if (!isupper(prenom[0])) {
        prenom[0] = toupper(prenom[0]); // Met la première lettre en majuscule
    }
}
  • On peut tout faire directement dans le main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
int main() {
    char** tabPrenom = NULL;
    int nbPrenoms;

    // Demander à l'utilisateur combien de prénoms il souhaite stocker
    nbPrenoms = better_scan_pos("Combien de prénoms souhaitez-vous stocker ? \n");
    // Allouer de l'espace pour le tableau de pointeurs vers les prénoms
    tabPrenom = (char**)malloc(nbPrenoms * sizeof(char*));
    if (tabPrenom == NULL) {
        printf("Erreur d'allocation de mémoire.\n");
        exit(EXIT_FAILURE);
    }

    // Saisir et stocker chaque prénom dans le tableau
    for (int i = 0; i < nbPrenoms; i++) {
        int taillePrenom;
        printf("Entrez la taille du prénom %d ", i + 1);
        taillePrenom = better_scan_pos(": \n");

        // Allouer de l'espace pour le prénom et ajouter 1 pour le caractère de fin de chaîne '\0'
        tabPrenom[i] = (char*)malloc((taillePrenom + 1) * sizeof(char));
        if (tabPrenom[i] == NULL) {
            printf("Erreur d'allocation de mémoire.\n");
            exit(EXIT_FAILURE);
        }

        // Saisir le prénom
        printf("Entrez le prénom %d : ", i + 1);
        if (fgets(tabPrenom[i], taillePrenom + 1, stdin)==NULL){
            exit(EXIT_FAILURE);
        }
        tabPrenom[i][strcspn(tabPrenom[i], "\n")] = 0;
    }

    AfficherPrenom(tabPrenom, nbPrenoms);

    // Libérer la mémoire
    for (int i = 0; i < nbPrenoms; i++) {
        free(tabPrenom[i]);
    }
    free(tabPrenom);

    return 0;
}

EXIT_FAILURE est définie dans stdlib et permettent une meilleur lecture du code, exit() permet de sortir du programme avec un code d’erreur. fgets prend en argument la variable où stocker la valeur d’entrée, le nombre maximum de char qu’elle doit enregistrer et pour finir le stream qu’elle doit lire (ici stdin) cette fontion renvoie un pointeur vers la chaîne de char si la fonction échoue elle renvoie NULL, strcspn prend en argument une chaîne de char et une liste (chaîne de char) de rejet, Elle Renvoie la longueur de la plus grande sous-chaîne (en partant du début de la chaîne initiale) ne contenant aucun des caractères spécifiés dans la liste des caractères en rejet, ici elle permet de trouver l’index avant le \n.

Exercice 4

exercice 4

  • On importe tout d’abord toute les librairies utiles et on crée directement le programme dans le main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    // Vérifie si le nombre d'arguments est correct
    if (argc != 4) {
        printf("Usage: %s <nombre1> <opérateur> <nombre2>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    // Convertit les arguments en nombres réels
    double nombre1 = atof(argv[1]);
    double nombre2 = atof(argv[3]);

    // Effectue l'opération en fonction de l'opérateur
    double resultat;
    char operateur = argv[2][0]; // Prend le premier caractère de l'opérateur
    switch (operateur) {
        case '+':
            resultat = nombre1 + nombre2;
            break;
        case '-':
            resultat = nombre1 - nombre2;
            break;
        case '*':
            resultat = nombre1 * nombre2;
            break;
        case '/':
            // Vérifie si la division par zéro
            if (nombre2 == 0) {
                printf("Erreur: Division par zéro\n");
                exit(EXIT_FAILURE);
            }
            resultat = nombre1 / nombre2;
            break;
        default:
            printf("Erreur: Opérateur non valide\n");
            exit(EXIT_FAILURE);
    }

    // Affiche le résultat
    printf("Résultat de l'opération : %f\n", resultat);

    return EXIT_SUCCESS;
}

EXIT_SUCCESS et EXIT_FAILURE sont définie dans stdlib et permettent une meilleur lecture du code, exit() permet de sortir du programme avec un code d’erreur.

Exercice 5

exercice 5 exercice 5_2

  • On commence par importer les bibliothèque et on crée nos deux fonctions de saisie
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <stdlib.h>

int better_scan_pos(char * message){
    int ret_var = 0;
    int value = 1;
    while (ret_var != 1 || value < 0)
    {   
        printf(message);
        ret_var = scanf("%d", &value);
        while(getchar()!='\n'){} // Ligne facultative de sécurisation
    }
    return value;
    
}

int choixNMax(){
    int n = better_scan_pos("Choisir n_max : \n");
    return n;
}

La ligne while(getchar()!='\n'){} est facultative elle permet de vider le buffer et d’avoir un scanf qui ne boucle pas a l’infinie lors d’une mauvaise saisie.

Question 2 : Le triangle de pascal doit faire \(n+1\) lignes

  • On crée la fonction crée triangle en utilisant les formules donnée dans l’énoncée
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int** creerTriangle(int n_max){

    int** result = (int**)malloc((n_max+1)*sizeof(int*)); // on alloue la mémoire
    if (result == NULL){
        exit(EXIT_FAILURE); 
    }

    for (int i = 0; i < n_max+1; i++)
    {
        result[i] = (int*)malloc((i+1)*sizeof(int)); // on alloue la ligne
        if (result[i] == NULL){
            exit(EXIT_FAILURE);
        }
        
        for (int j = 0; j < i+1; j++) //pour chaque Nouvelle ligne on calcule les coef
        {                             // en fonction des regles donnée 
            if (j == 0 || j == i){
                result[i][j] = 1;
            } else {
                result[i][j] = result[i-1][j-1] + result[i-1][j];
            }

        }      
    }
    return result;
}

EXIT_SUCCESS et EXIT_FAILURE sont définie dans stdlib et permettent une meilleur lecture du code, exit() permet de sortir du programme avec un code d’erreur.

On peut aussi aborder une approche récursive de la fonction en ayant pour conditions d’arret les conditions donnée dans l’exercice.

  • On crée la procédure d’affichage demandée en Parcourant le tableau
1
2
3
4
5
6
7
8
9
10
11
void affichePascal(int **tab, int n_max){
    for (int i = 0; i < n_max+1; i++)
    {
        for (int j = 0; j < i+1; j++)
        {
            printf("%d ", tab[i][j]);
        }
        printf("\n");
    }
    
}
  • On peut tester tout cela dans le main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main(){
    int n_max = choixNMax();

    int** triangle = creerTriangle(n_max);

    affichePascal(triangle, n_max);

    int n = n_max + 2;
    int k = n_max + 2;
    while (n > n_max+1) //on verifie les conditions demandée
    {
        n = better_scan_pos("choisir n :\n"); // si on utilise un scanf il faudra augmenter le nombre de conditions 
    }
    while (k > n_max+1)
    {
        k = better_scan_pos("choisir k :\n");
    }

    printf("Résultat : de %d parmis %d : %d \n", k,n,triangle[n][k]);
}
Cet article est sous licence BSD 2-Close licence par l'auteur.