Skip to content

Latest commit

 

History

History
368 lines (244 loc) · 11.1 KB

qcm_avances.rst

File metadata and controls

368 lines (244 loc) · 11.1 KB
.. author::

    Pablo Gonzalez Alvarez

Les Tableaux

QCM Avancés

Question 1 - Assertions

En Java, les assertions peuvent être utilisées pour vérifier explicitement les préconditions et les postconditions d'une méthode. En programmation défensive, on utilise des assert pour vérifier explicitement les préconditions de chaque méthode. Considérons la méthode dont la spécification est reprise ci-dessous :

/**
 * @pre a>0, b>2*a et b est pair
 * @post ....
 */
private void methode(int a, int b)

Laquelle des séquences d'instructions ci-dessous vérifie explicitement les préconditions de cette méthode ?

  • assert a>0 : "a doit être strictement positif";
    assert ( (b>2*a) && (b%2)==0 ) : "b invalide";

    Notez qu'en Java l'expression (b%2) est une expression entière. Elle peut donc apparaître à gauche d'un signe ==. Il est intéressant d'utiliser des commentaires pour indiquer quelle précondition n'est pas vérifiée.

  • assert a>0 : "a doit être strictement positif";
    assert (b>2*a) : "b trop petit";
    int reste=b%2;
    assert reste==0 : "b n'est pas pair";

    Il est intéressant d'utiliser des commentaires pour indiquer quelle précondition n'est pas vérifiée.

  • assert a<=0;
    assert ( (b>2*a) && (b%2)==0 ) : "b invalide";

    La première assertion est incorrecte. Elle est vraie lorsque a<=0 or la précondition de la méthode est a>0.

  • int reste=b%2;
    assert a<=0 : "a doit être strictement positif";
    assert reste!=0 : "b n'est pas pair";
    assert (b<=2*a) : "b trop petit";

    En Java, assert permet de vérifier qu'une précondition est remplie. Si c'est le cas, l'instruction assert n'a aucun effet. Sinon, l'instruction assert affiche le message qui suit : et provoque une erreur. Lorsque l'on utilise assert pour vérifier les préconditions, on souhaite que l'exécution du programme s'arrête et que le message d'erreur soit afficher lorsqu'une précondition n'est pas vérifiée. Pour cela, l'expression booléenne contenu dans l'assertion doit être la précondition à vérifier.

  • assert a<=0 : "a doit être strictement positif";
    assert ( (b<=2*a) && (b%2)!=0 ) : "b invalide";

    Notez qu'en Java l'expression (b%2) est une expression entière. Elle peut donc apparaître à gauche d'un signe ==. En Java, assert permet de vérifier qu'une précondition est remplie. Si c'est le cas, l'instruction assert n'a aucun effet. Sinon, l'instruction assert affiche le message qui suit : et provoque une erreur. Lorsque l'on utilise assert pour vérifier les préconditions, on souhaite que l'exécution du programme s'arrête et que le message d'erreur soit afficher lorsqu'une précondition n'est pas vérifiée. Pour cela, l'expression booléenne contenu dans l'assertion doit être la précondition à vérifier.

Question 2 - Somme de vecteurs

Considérons les tableaux a, b et s déclarés comme indiqués ci-dessous :

int[] a= newint[20];
int[] b= new int[20];
int[] s= new int[20];

Supposons que ces tableaux servent à stocker des vecteurs (au sens mathématique du terme). Laquelle des séquences d'instructions ci-dessous place-t-elle dans le vecteur s la somme des vecteurs a et b?

  • for(int i=0; i<a.length;i++) {
     s[i]=a[i]+b[i];
    }
  • for(int i=0; i<b.length;i++) {
     s[i]=a[i]+b[i];
    }
  • for(int i=s.length-1; i>=0;i=i-1) {
     s[i]=a[i]+b[i];
    }
  • s[]=a[]+b[];

    Cette instruction est invalide en Java. Il est nécessaire d'utiliser une boucle pour calculer cette somme.

  • for(int i=0; i<=a.length;i++) {
     s[i]=a[i]+b[i];
    }

    Cette boucle va provoquer une erreur à l'exécution lorsque i vaut a.length. Voyez-vous pourquoi ?

  • for(int i=0; i<=b.length;i++) {
     s[i]=a[i]+b[i];
    }

    Cette boucle va provoquer une erreur à l'exécution lorsque i vaut b.length. Voyez-vous pourquoi ?

  • for(int i=s.length-1; i>0;i=i-1) {
     s[i]=a[i]+b[i];
    }

    Cette boucle ne calculera pas la valeur de s[0]. Voyez-vous pourquoi ?

  • for(int i=s.length; i>=0;i=i-1) {
     s[i]=a[i]+b[i];
    }

    Cette boucle va provoquer une erreur à l'exécution lorsque i vaut s.length. Voyez-vous pourquoi ?

Question 3 - Tableaux de caractères

La semaine passée, vous avez écrit une méthode count permettant de déterminer le nombre d'occurences d'un caractère dans un String. Lequel des corps ci-dessous est une implémentation correcte de la méthode isIn dont la spécification est

/*
 * @pre chaîne s non vide
 * @post retourne true si le caractère c est présent dans la chaîne s
 *       et false sinon
 */
public static boolean isIn(char c, char[] s)
  • for(int i=0;i<s.length;i++) {
      if(s[i]==c) {
         return true;
      }
    }
    return false;
  • for(int i=s.length-1;i>=0;i=i-1) {
      if(s[i]==c) {
         return true;
      }
    }
    return false;
  • for(int i=0;i<s.length();i++) {
      if(s[i]==c) {
         return true;
      }
    }
    return false;

    Le nombre d'éléments dans le tableau de caractère s est s.length et non le résultat de l'application d'une méthode length() qui ne prend pas de paramètre.

  • for(int i=0;i<=s.length;i++) {
      if(s[i]==c) {
         return true;
      }
    }
    return false;

    Nok

  • for(int i=0;i<s.length();i++) {
      if(s[i]==c) {
         return true;
      }
      else {
         return false;
      }
    }

    Que fait cette méthode après avoir comparé c avec l'élément s[0] ?

Question 4 - toCharArray

La classe String contient une méthode baptisée toCharArray() qui permet de convertir un String en un tableau de caractères. Une méthode statique équivalent pourrait avoir les spécification et signature suivantes :

/*
 * @pre chaîne s non vide
 * @post retourne un tableau de caractères ayant le même contenu que
 *       que String passé en paramètre
 */
public static char[] toCharArray(String s)

Laquelle des séquences ci-dessous est une implémentation correcte de cette méthode ?

  • char[] r = new char[s.length()];
    for(int i=0;i<s.length();i++) {
       r[i]=s.charAt(i);
    }
    return r;

    Notez que la longueur d'une chaîne de caractères s'obtient en appliquant la méthode length() à une référence vers cette chaîne. La longueur du tableau de caractères r est r.length.

  • char[] r = new char[s.length()];
    for(int i=s.length()-1;i>=0;i=i-1) {
      r[i]=s.charAt(i);
    }
    return r;

    Notez que la longueur d'une chaîne de caractères s'obtient en appliquant la méthode length() à une référence vers cette chaîne. La longueur du tableau de caractères r est r.length.

  • char[] r;
    for(int i=0;i<s.length();i++) {
        r[i]=s.charAt(i);
    }
    return r[];

    Cette réponse contient deux erreurs. Tout d'abord, avant de pouvoir utiliser un tableau, il faut fixer sa longueur lors de son initialisation. Ensuite, pour retourner un tableau, il faut retourner une référence vers ce tableau. Si r est une référence de type char[], il suffit de

  • char[] r = s;
    return r;

    En Java, ce genre de raccourci n'existe pas.

  • char[] r = new char[s.length];
    for(int i=0;i<s.length;i++) {
        r[i]=s.charAt(i);
    }
    return r;

    En Java, la longueur d'une chaîne de caractères s'obtient via s.length() et non s.length.

Vérifiez vos réponses

.. author::

    Pablo Gonzalez Alvarez