Jean-Jacques BOURDIN Liste d‘execrcices

    Remarques :

    Vous ne devez pas faire tous les exercices s‘ils vous paraissent facile.

    N‘oubliez pas de faire des fonctions main pour valider vos exercices.

    Facile

  1. la fonction qui trouve le plus grand parmi trois nombres entiers ;
  2. la fonction qui trouve le plus grand parmi quatre nombres entiers ;
  3. la fonction qui trouve le plus petit parmi cinq nombres entiers ;
  4. la fonction qui trouve le second plus grand parmi trois nombres entiers ;
  5. la fonction qui trouve le second plus grand parmi quatre nombres entiers ;
    sec4(7,3,2,9)==7
  6. la fonction qui trouve le second plus grand parmi cinq nombres entiers ;

    Récursions

  7. Somme des carrés des n premiers entiers
  8. Somme des cubes des n premiers entiers
  9. Somme des puissance quatre des n premiers entiers
  10. Produit des n premiers entiers
  11. Produit des carrés des n premiers entiers
  12. Produit des cubes des n premiers entiers
  13. Produit des puissances quatre des n premiers entiers
  14. Exponentiation (x puissance n)
  15. Somme des puissances p des n premiers entiers
    sompn(2,4) = 0^4 + 1^4 + 2^4 = 17
  16. Additions par incrémentations successives
    On suppose ne savoir faire des additions que de +1 ou -1.
    L‘addition de deux valeurs add(a+b) peut être ramenée à l‘addition de a+1 et celle de b-1 n‘est-ce pas ?
    Écrivez la fonction récursive qui fait ainsi l‘addition de deux valeurs.
  17. Soustractions de deux valeurs
    Ici encore avec uniquement des +1 et -1.
  18. Multiplication russe
    Il s‘agit de faire la multiplication par additions successives.
  19. Division entière et récursive
  20. Reste de la Division entière
  21. Plus grand diviseur commun de deux entiers
  22. Plus petit multiple commun de deux entiers
  23. Élément n de la suite de Fibonacci.
  24. Récursivité terminale

  25. Somme des carrés des n premiers entiers
  26. Somme des cubes des n premiers entiers
  27. Somme des puissance quatre des n premiers entiers
  28. Produit des n premiers entiers
  29. Produit des carrés des n premiers entiers
  30. Produit des cubes des n premiers entiers
  31. Produit des puissances quatre des n premiers entiers
  32. Exponentiation (x puissance n)
  33. Somme des puissances p des n premiers entiers
    sompn(2,4) = 0^4 + 1^4 + 2^4 = 17
  34. Additions par incrémentations successives
    On suppose ne savoir faire des additions que de +1 ou -1.
    L‘addition de deux valeurs add(a+b) peut être ramenée à l‘addition de a+1 et celle de b-1 n‘est-ce pas ?
    Écrivez la fonction récursive qui fait ainsi l‘addition de deux valeurs.
  35. Soustractions de deux valeurs
    Ici encore avec uniquement des +1 et -1.
  36. Multiplication russe
    Il s‘agit de faire la multiplication par additions successives.
  37. Division entière et récursive
  38. Plus petit multiple commun de deux entiers
  39. Élément n de la suite de Fibonacci.
  40. Itérations

    Faire avec des while, des do while, des for et des goto les fonctions suivantes :
  41. Somme des carrés des n premiers entiers
  42. Somme des cubes des n premiers entiers
  43. Somme des puissance quatre des n premiers entiers
  44. Produit des n premiers entiers
  45. Produit des carrés des n premiers entiers
  46. Produit des cubes des n premiers entiers
  47. Produit des puissances quatre des n premiers entiers
  48. Exponentiation (x puissance n)
  49. Somme des puissances p des n premiers entiers
    sompn(2,4) = 0^4 + 1^4 + 2^4 = 17
  50. Additions par incrémentations successives
    On suppose ne savoir faire des additions que de +1 ou -1.
    L'addition de deux valeurs add(a+b) peut être ramenée à l'addition de a+1 et celle de b-1 n'est-ce pas ?
    Écrivez la fonction itérative qui fait ainsi l'addition de deux valeurs.
  51. Soustractions de deux valeurs
    Ici encore avec uniquement des +1 et -1.
  52. Multiplication russe
    Il s‘agit de faire la multiplication par additions successives.
  53. Division entière itérative
  54. Reste de la Division entière
  55. Plus grand divieur commun de deux entiers
  56. Plus petit multiple commun de deux entiers
  57. Vecteurs

  58. Refaire tous les exercices itératifs en remplissant un vecteur au fur et à mesure et en utilisant les valeurs déjà dans le vecteur pour calculer les nouvelles, sur l‘exemple de somvec.
  59. Faire une fonction qui renvoie le nombre d‘éléments nuls du vecteur.
  60. Faire une fonction qui renvoie le nombre d‘éléments du vecteur égaux à un certain x.
  61. Faire une fonction qui renvoie la première valeur du vecteur qui soit le carré d‘un entier ou -1 sinon.
  62. Faire une fonction qui renvoie la somme des valeurs du vecteur.
  63. Faire une fonction qui renvoie la somme des valeurs du vecteur inférieures à x.
  64. Faire une fonction qui affiche les valeurs du vecteur dans l‘ordre inverse.
  65. Faire une fonction qui renvoie la plus grande valeur du vecteur.
  66. Faire une fonction qui renvoie la plus petite valeur du vecteur.
  67. Faire une fonction qui renvoie la seconde plus petite valeur du vecteur.
  68. Faire une fonction qui renvoie la moyenne des valeurs du vecteur.
  69. Faire une fonction qui renvoie la médiane des valeurs du vecteur.
  70. Faire une fonction qui renvoie l‘écart-type du vecteur.
  71. Faire une fonction qui replace les valeurs du vecteur dans l‘ordre inverse.
  72. Fabriquez un autre vecteur dans lequel vous mettrez en premier l‘élément le plus grand élément du vecteur initial, puis en second le second plus grand, puis le troisième et ainsi de suite, le dernier élément du second vecteur sera le plus petit du vecteur de départ. Affichez le vecteur ainsi rangé.

    vecteur initial : [8, 13, 21, 11, 9, 20, 6, 3, 9, 12]
    Vecteur final : [21, 20, 13, 12, 11, 9, 9, 8, 6, 3]

  73. Faire une fonction qui insère une valeur dans un vecteur rangé en ordre décroissant.
    insere([1,2,6,9,10],5,8) donne un vecteur de 6 éléments : [1,2,6,7,8,9,10].
  74. Faire une fonction qui trie le vecteur dans l‘ordre décroissant grâce à la fonction ci-dessus.
  75. Faire une fonction qui trie le vecteur dans l‘ordre décroissant grâce à la fonction quicksort.
  76. Structures

    Nous utilisons maintenant la structure suivante :
    typedef struct table_alt {
      int larg;
      int haut;
      float t[100][100];
    } table_alt_t;
    
       /*  table_alt_t est un type qui contient
       - deux valeurs de taille et
       - un vecteur float [100][100]*/
     
    Voici une fonction pour afficher un tel vecteur :
    void affiche (table_alt_t t) {
      int x, y, sx, sy;
      sx = t.larg;
      sy = t.haut;
      printf("Tailles max %d et %d\n", t.larg, t.haut);
      for (x = 0; x < sx; x = x + 1) {
        for (y = 0; y < sy; y = y + 1)
          printf("%5.2f\t", t.t[x][y]);
        printf("\n");
      }
    }
    
    Et une fonction pour le remplir de valeurs :
    table_alt_t remplirt (int sx, int sy) {
      int x, y, sxy;
      float v, eps, add, pas;
      table_alt_t tt;
    
      tt.larg = sx;
      tt.haut = sy;
      pas = 0.5;
      v = pas;
      add = 5.0;
      sxy = sx * sx + sy * sy;
      eps = 100.0 / (float) (sxy);
      for (x = 0; x < sx; x += 1) {
            for (y =  0; y < x; y += 1) {
              tt.t[x][y] = (float) (x * x - y * y + add) * eps;
            }
            for (y =  x; y < sy; y += 1) {
              tt.t[x][y] = (float) ( y * y - x * x + add) * eps;
            }
            /*
            for (y = 0; y < sy; y = y + 1)
              printf("%f \t", (*tt).t[x][y]);
            printf("\n");
            */
            add += v;
            if (add > 10.0)
              v = - pas;
            if (add < 0.1)
              v = pas;
      }
      return tt;
    }
    

    Note : le dénivelé entre deux points et la différence d‘altitude entre ces deux points.
    Un dénivelé positif est un dénivelé dont la valeur est positive (montée).
    Un dénivelé négatif est un dénivelé dont la valeur est négative (descente).
    Il vous reste à écrire les fonctions qui permettent de :

  77. Trouver le point culminant (la valeur la plus grande) d‘une certaine ligne horizontale.
  78. Trouver le point culminant d‘une certaine colonne.
  79. Trouver le point culminant de toute la surface.
  80. Trouver le second point culminant de toute la surface.
  81. Calculer le dénivelé entre deux points donnés.
  82. Calculer la somme des dénivelés entre deux points d‘une ligne. Il faut donc que le numéro de la ligne soit fourni en argument.
  83. Calculer la somme des dénivelés entre deux points d‘une colonne. Il faut donc que le numéro de la colonne soit fourni en argument.
  84. Calculer la somme des dénivelés positifs entre deux points le long d‘une ligne.
  85. Calculer la somme des dénivelés négatifs entre deux points le long d‘une colonne.
  86.  

    Avec les nombres complexes et les vecteurs de nombres complexes 
    struct complex mulc (struct complex a, struct complex b) {
      struct complex res;
      res.real = a.real + b.real;
      res.imag = b.imag + a.imag;
      return res;
    }
    struct vecc {
      int nbe;
      complex tab [100];
    };
    typedef struct vecc vecc_t ;
    
    Donnez les fonctions qui calculent :
  87. La différence entre deux complexes.
  88. Soit un x, la somme des complexes du vecteur dont le module est supérieur à x.
  89. Le second plus grand nombre complexe (utilisation du module, de même que pour toute la suite),
  90. le troisième plus petit,
  91. le quatrième plus grand,
  92. ranger tout ce tableau dans l‘ordre des modulos décroissants en utilisant l‘algorithme tri par insertion,
  93. ranger tout ce tableau dans l‘ordre des modulos décroissants en utilisant l‘algorithme quicksort.
  94.  

    En utilisant des pointeurs pour accéder aux cases du vecteur :

  95. pour deux points voisins, (i1,j1) et (i2,j2) donner le dénivelé entre les deux.
  96. pour deux points de la même horizontale, donner la somme des dénivelés positifs entre eux.
  97. pour deux points de la même verticale, donner la somme des dénivelés positifs entre eux.
  98. pour deux points de la même verticale, donner la somme des dénivelés positifs et la somme des dénivelés négatifs entre eux. (utilisation d‘une structure ad hoc).
  99. pour deux points donnés, calculer les dénivelés positifs et négatifs entre eux, selon la droite qui les joint.
  100. Listes

    Attention, cette définition est légèrement différente de celle donnée en cours.

    typedef struct cell * liste_t;
    typedef struct cell {
      float obj;
      struct cell * suiv;
    } cell_t;
    

    Here you see that a list is only the adress of a structure.

    Où on voit que la liste est en fait uniquement l'adresse d'une structure qui contient une valeur et une liste.

  101. fonctions simples
    int estvide (liste_t l) {
      if (l == (liste_t) 0) {
        return 1;
      }
      return 0;
    }
    int estnonvide (liste_t l) {
      if (l == (liste_t) 0) {
        return 0;
      }
      return 1;
    }
    
  102. La somme des éléments
    float soml (liste_t l) {
      if (estvide(l)) {
        return 0.0;
      }
      return (*l).obj + soml((*l).suiv);
    }
    
  103. Le nombre d‘éléments
    int howmany (liste_t l) {
      if (estvide(l)) {
        return 0;
      }
      return 1 + howmany ((*l).suiv);
    }
    
  104. La construction
    liste_t cons (float nb, liste_t l) {
      liste_t new;
      new = (liste_t) malloc (sizeof(cell_t));
      assert(new);
      (*new).obj = nb;
      (*new).suiv = l;
      return new;
    }
    liste_t creercours (int nb) {
       liste l;
       int i;
       float x;
       x = 0.1;
       l = (liste_t) 0;;
       while (nb--) {
          l = cons (x, l);
          x += 0.15;
          if (x > 0.5)
             x -= 0.45;
       }
       return l;
    }
    liste_t creeriter (int nb) {
      liste_t debut;
      int i, j, k, t;
      j = 13;
      k = 21;
      debut = (liste_t) 0;
      for (i = 0; i < nb; i++) {
        debut = cons (j, debut);
        t = (j + k) % 31;
        k = j;
        j = t;
      }
      return debut;
    }
    		  
  105. Trois fonctions d‘affichage
    void affl (liste_t l) {
      if (estvide (l)) {
        printf("\n");
      }
      else {
        printf("%5.2f ", (*l).obj);
        affl ((*l).suiv);
      }
    }
    
    Liste d‘exercices à faire.
    1. Trouver le plus grand élément.
    2. Afficher les éléments dans l‘ordre inverse.
    3. Mettre les éléments de la liste en ordre inverse. (Attention, il n‘y a pas besoin de malloc pour faire cette fonction).
    4. Fabriquer une liste avec les n premiers entiers (dans l‘ordre décroissant).
    5. Faire la somme des éléments d‘une liste.
    6. Faire la somme des éléments plus petits que 50 d‘une liste.
    7. Faire la moyenne des éléments d‘une liste.
    8. Enlever le premier élément d‘une liste.
    9. Enlever le dernier élément d‘une liste.
    10. Fonction de concaténation de deux listes.
    11. Dans une liste rangée, insérer une cellule à sa place.
    12. Faire le tri d‘une liste, par insertion.
    13. Trouver le médian des éléments d‘une liste.
    14. Fabriquer une liste des carrés de tous les éléments d‘une autre liste passée en paramètre.

        III.D) Arbres

    Voici une structure puis les fonctions de remplissage d‘un arbre.

    /* Arbres binaires tout simplement */
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    struct noeud {
      int num;
      float val;
      struct noeud * fg;
      struct noeud * fd;
    } ;
    
    typedef struct noeud noeud;
    typedef struct noeud * arbre_t;
    
    arbre_t ajout (arbre_t a, int v, float x) {
      arbre_t new;
      int rande;
      if (! a) {
    	new = (arbre_t) malloc (sizeof (noeud));
    	new->num = v;
    	new->val = x;
    	new->fg = (arbre_t) 0;
    	new->fd = (arbre_t) 0;
    	return new;
      }
      rande = rand ();
      /*
      printf(" insere %d en %d avec %2d\n", v, a->num, rande %10);
      */
      if (rande % 2) {
    	/* on le met à gauche*/
    	if (! (a->fg)) {
    	  /* s‘il ny a pas de fils gauche */
    	  a->fg = (arbre_t) malloc (sizeof (noeud));
    	  a->fg->num = v;
    	  a->fg->val = x;
    	  a->fg->fg = (arbre_t) 0;
    	  a->fg->fd = (arbre_t) 0;
    	  return a;
    	}
    	a->fg = ajout(a->fg, v, x);
    	return a;
      }
      /* on le met donc a droite*/
      if (! (a->fd)) {
    	/* s‘il ny a pas de fils droit */
    	a->fd = (arbre_t) malloc (sizeof (noeud));
    	a->fd->num = v;
    	a->fd->val = x;
    	a->fd->fg = (arbre_t) 0;
    	a->fd->fd = (arbre_t) 0;
    	return a;
      }
      a->fd = ajout(a->fd, v, x);
      return a;
    }
    /*
    To create the tree, you add, one after the other, the values in the
    tree.*/
    arbre_t creation (int n) {
      arbre_t a;
      float x, y;
      x = 1.5;
      y = 0.21;
      a = (arbre_t) 0;
      srand(time(NULL));
      while (n--) {
    	a = ajout (a, n, x);
    	x += y;
    	y += 0.06;
    	if (x > 3.0 || x < -2.0) {
    	  y = - y;
    	}
      }
      return a;
    }
    
    int appartient (int nu, arbre_t a) {
      if (! a)
        return 0;
      if (a->num == nu)
        return 1;
      if (appartient (nu, a->fd))
        return 1;
      return appartient (nu, a->fg);
    }
    
    Vous pouvez aussi :
    • Trouver le plus grand val dans un arbre_t.
    • Trouver le second plus petit val dans un arbre.
    • Compter le nombre de noeuds de l‘arbre.
    • Compter le nombre de noeuds dont le champ val est supérieur à une valeur donnée.
    • Compter le nombre de feuilles de l‘arbre (une feuille est un noeud qui n‘a aucun successeur).
    • Renvoyer la profondeur d‘un noeud de l‘arbre. La profondeur est le nombre de générations entre la racine de l‘arbre et la cellule cherchée. La racine est à la profondeur 0, ses successeurs directs à la profondeur 1, etc.
    • Renvoyer la profondeur maximale de l‘arbre.

    Dernière mise à jour le 12/9/2024 10h00