User Tools

Site Tools


in204:tds:sujets:td7:part3

This is an old revision of the document!


Partie III – Algorithmes génériques

Dans la conclusion du cours, nous affirmons qu’un intérêt du polymorphisme, c’est de pouvoir écrire un algorithme « générique », c’est à dire un algorithme qui pourra fonctionner pour des objets représentant des données de plusieurs types.

Nous considérons un algorithme de tri très simple qui fonctionne sur des entiers :

void insertion_sort(std::vector<int>& anArray)
{
	for (int i = 0; i < anArray.size(); i++)
	{
		for (int j = i + 1; j < anArray.size(); j++)
		{
			if (anArray[i] > anArray[j])
				std::swap(anArray[i], anArray[j]);
		}
	}
}

Cet algorithme fonctionne uniquement pour des entiers. Nous nous proposons de transformer cette fonction afin qu’elle puisse aussi bien trier des entiers mais aussi des réels ou des complexes.

Question n° 1

Pour ce faire, nous concevons une classe « abstraite » ayant comme nom « Base » qui expose les fonctions nécessaires à l’écriture de l’algorithme de tri.

Nous souhaitons utiliser l’algorithme avec la signature suivante :

void insertion_sort(std::vector<Base*>& anArray)

Quelles sont les méthodes virtuelles que la classe abstraite doit exposer ?

Correction

Correction

La classe doit exposée une méthode permettant de déterminer si un élément est plus grand que l'autre. Il peut s'agit soit d'une méthode testant si un élément est plus grand que l'autre :

class Base
{
public: 
    virtual bool isGreater(const Base&) const = 0; 
        // Retourne true si l'objet courant est plus grand.
    ...
};

Nous pouvons ajouter éventuellement des méthodes complémentaires comme :

    virtual bool isGreaterOrEqual(const Base&) const = 0; 
    virtual bool isLess(const Base&) const = 0; 
    virtual bool isLessOrEqual(const Base&) const = 0; 
    virtual bool isEqual(const Base&) const = 0; 
    virtual bool isNotEqual(const Base&) const = 0; 

Voire éventuellement une fonction compareTo:

    virtual int compareTo(const Base&) const = 0;
       // retourne -1 si l'instance courante est plus petite que l'instance passée en paramètre
       // retourne 0 si elles sont égales
       // retourne 1 si l'instance courante est plus grande que l'instance passée en paramètre.

Question n° 2

Question n° 2.1

Ajouter à la classe de base Base une méthode purement virtuelle print() qui affiche le contenu de la classe sur la console.

Question n° 2.2

Créer une fonction print(std::vector<Base*> anArray) qui prend un tableau en paramètre et affiche l’ensemble des éléments contenus dans le tableau sur la console.

Question n° 3

Question n° 3.1

Créer une classe Entier qui dérive de la classe « abstraite » Base et qui contient un champ m_value ayant comme type le type int.

Question n° 3.2

Créer une fonction qui crée un tableau de theNumberOfValues entiers de type Entier

std::vector<Base*> create_integer_array(
	size_t theNumberOfValues)

qui crée un tableau de theNumberOfValues valeurs commençant par la valeur 0 et se terminant à la valeur theNumberOfValues-1.

Question n° 3.3

Créer une fonction qui crée un tableau de theNumberOfValues entiers de type Entier dont les éléments sont des nombres aléatoires compris entre theMinValue et theMaxValue.

Cette fonction peut s’implanter comme suit.

std::vector<Base*> create_random_integer_array(
	size_t theNumberOfValues, int theMinValue, int theMaxValue)
{
	std::random_device rd;
	std::mt19937 gen(rd());	
	std::uniform_int_distribution<> distr(theMinValue, theMaxValue);
	std::vector<Entier*> array(theNumberOfValues);
	for (size_t i = 0; i < theNumberOfValues; i++)
		array[i] = new Entier(distr(gen));
	return array;
}

Question n°4

Modifier la fonction de tri insertion_sort(std::vector<int>& anArray) afin de ne plus travailler sur des entiers mais sur des objets dérivant de la classe « abstraite » Base :

void insertion_sort(std::vector<Base*>& anArray)

Tester la fonction avec le tableau d’entiers que vous avez créé à la question n°3.3.

Question n° 5

Nous souhaitons étendre le code à une classe de réel.

Question n° 5.1

Ecrire une nouvelles classe Reel qui dérive de Base et qui contient un champ m_value de type double.

Question n° 5.2

Créer une fonction qui crée un tableau de theNumberOfValues objets de type Reel dont les éléments sont des nombres aléatoires compris entre theMinValue et theMaxValue.

Cette fonction peut s’implanter comme suit.

std::vector<Base*> create_random_double_array(
	size_t theNumberOfValues, double theMinValue, double theMaxValue)
{
	std::random_device rd;
	std::mt19937 gen(rd());
	std::uniform_real_distribution<> distr(theMinValue, theMaxValue);
	std::vector<Base*> array(theNumberOfValues);
	for (size_t i = 0; i < theNumberOfValues; i++)
		array[i] = new Real(distr(gen));
	return array;
}

Vérifier que l’algorithme de tri fonctionne aussi pour cette nouvelle nouvelle classe.

in204/tds/sujets/td7/part3.1603190708.txt.gz · Last modified: 2020/10/20 10:45 by bmonsuez