Ordinateurs

Trier les objets dans la liste C++ via le prédicat de comparaison

Je suis un ingénieur logiciel. Je travaille avec les technologies C++, MFC et net depuis 15 ans. J’aime les jeux vidéo et lire des livres.

Qu’est-ce que le prédicat de comparaison ?

Nous savons que le tri peut être effectué en comparant deux éléments et en organisant les éléments soit par ordre croissant, soit par ordre décroissant. Pour toute API de programmation, ce sera une tâche facile lorsque les éléments relèvent de types de données standard tels que des entiers, des flottants, etc. Maintenant, lorsque le type est défini par l’utilisateur, disons par exemple ; instance de classe, l’API peut ne pas savoir comment trier les éléments. Ou, même si c’est le cas, ce n’est peut-être pas comme nous le voulons. Et c’est là que le besoin de la « Comparer le prédicat » entre en scène.

Dans cet article, nous allons créer une classe Department et trier les instances de celle-ci via quelques prédicats de comparaison. Commençons.

La classe Department : pour expliquer le tri de liste C++

Le code ci-dessous montre la classe de département complète :

//ListSort 01: Department class fot this Hub
class Department
{
private:
	//1.1: Private Members
	int m_DeptID;
	string m_DeptName;
	int m_NumberOfStaffs;

public:
	//1.2: Department Class Constructor
	Department(int id, string name, int total_emp)
	{
		m_DeptID = id;
		m_DeptName = name;
		m_NumberOfStaffs = total_emp;
	}

	//1.3: Getter Functions
	int GetDeptId() 
	{
		return m_DeptID;
	}

	int GetNumberOfStaffs()
	{
		return m_NumberOfStaffs;
	}

	//1.4: Print Content of the Department Class
	void Print_Department()
	{
		cout << "Department - " << m_DeptName << "  ID:"
			<< m_DeptID << ", Total Staffs - " 
			<< m_NumberOfStaffs << endl;
	}
};

Extrait de code 1.1 : Membres

La classe de département a trois membres pour stocker l'identifiant du département, le nom et le nombre d'employés employés par le département. Ceci est montré dans l'extrait de code 1.1

Extrait de code 1.2 : Constructeur de département

Le constructeur prend trois paramètres et utilise ces paramètres passés pour initialiser tous ses membres. Notez que notre classe n'a pas d'autres constructeurs et qu'il n'y a pas non plus de constructeur par défaut. Cela garantira l'initialisation de tous les membres de données avec les données valides pendant la construction elle-même.

Extrait de code 1.3 : Fonctions getter

Nous avons donné deux fonctions getter qui renverront les membres privés m_DeptID et m_NumberOfStaffs.

A lire aussi :  Tâches de base à connaître dans Microsoft Word 365

Extrait de code 1.4 : Impression des informations sur le service

Le membre Print_Department() de la classe Department imprime les données Department dans la fenêtre de sortie de la console. Ici, nous utilisons le C++ iosteam pour lister les membres avec la chaîne concaténée. C'est tout à propos de la classe Department et explorons certaines des fonctions globales qui traitent de ces instances de classe Department et de la liste standard C++.

Ajout d'une instance de classe Department à la liste C++

La fonction globale Add_ListElements prend la liste standard C++ comme paramètre et y ajoute les instances de département. Le code de fonction est ci-dessous :

//ListSort 02: Function to Push some values to List
void Add_ListElements(list& listParam)
{
	//2.1: Clear the List
	listParam.clear();

	//2.2: Create Department Objects
	const Department D1(3, "Civil           ", 20);
	const Department D2(1, "Mechanical      ", 60);
	const Department D3(5, "Electrical      ", 22);
	const Department D4(4, "Chemical        ", 34);
	const Department D5(2, "Computer Science", 35);

	//2.3: Add Department Objects to List
	listParam.push_back(D1);
	listParam.push_back(D2);
	listParam.push_back(D3);
	listParam.push_back(D4);
	listParam.push_back(D5);
}

Extrait de code 2.1

Chaque fois que nous appelons Add_ListElements(), il doit ajouter cinq départements par défaut à la liste C++ fournie à des fins de démonstration. Par conséquent, d'abord, nous effaçons la liste en appelant la liste standard dégager() fonction.

Extrait de code 2.2

Cinq objets de département sont construits et notez que toutes les instances sont maintenues constantes car nous n'allons pas changer les membres de l'instance et nous n'effectuerons que le tri sur ces départements de démonstration.

Extrait de code 2.3

Nous stockons les départements un par un dans la liste standard C++ en utilisant le repousser() appel de fonction.

4. Itération des instances de classe de département dans la liste C++

Le Print_List () est écrit pour parcourir la liste fournie et imprime des informations sur la classe de département dans la fenêtre de la console. A chaque itération, nous récupérons l'instance de la classe Department et appelons son membre Print_Department() pour imprimer les informations du département Id, Name etc. La fonction ci-dessous :

//ListSort 03: Function to Print the Values in List
void Print_List(list listParam)
{
	list::iterator listItr;
	printf("\nThe contents of the Lists are:\n");
	for (listItr = listParam.begin();
		listItr != listParam.end();
		listItr++)
	{
		(*listItr).Print_Department();
	}
}

Comparer les prédicats pour trier les départements dans la liste

La liste standard "trier()" la fonction ne sait pas comment trier les types C++ définis par l'utilisateur, par exemple les structures, les objets de classe, etc. "Comparer les prédicats"nous pouvons apprendre à la fonction Sort() quand elle doit effectuer l'échange.

Le prédicat de comparaison attend deux paramètres et renvoie un booléen. Disons que les paramètres sont First et Second et que le corps du prédicat doit dire que cet ordre est bon ou mauvais. Lorsque nous disons que l'ordre est correct, nous devons renvoyer true sinon false. Lorsque le prédicat renvoie false, la fonction sort() de la liste standard sait que Second et First doivent être permutés afin que Second passe en premier dans l'ordre de tri.

Faites défiler pour continuer

Notez que les paramètres First et Second doivent correspondre au type de données du conteneur (dans cet exemple, il s'agit de Department).

5.1 Comparer le prédicat - Trier par ID de service

Notre première fonction de prédicat indique comment trier le département par son identifiant de département. Jetez un œil à la fonction de prédicat ci-dessous :

//ListSort 04a: Predicate function to sory by 
// Department IDs in Ascending order
bool Compare_IDS_Predicate_Asc(
	Department First, Department Next)
{
	//First Argument Stays First (Return true)
	if (First.GetDeptId() < Next.GetDeptId()) 
		return true; 

	//First Argument goes Next (Swap) (Return false)
	if (First.GetDeptId() > Next.GetDeptId()) 
		return false;

	//a==b. First Argument Stays first 
	//(No need to Swap)
	return true;
}

Dans le code ci-dessus, nous expliquons comment trier l'identifiant du département dans l'ordre croissant. Lorsque le paramètre First est inférieur au paramètre Second, nous ne voulons pas l'échanger, et donc nous renvoyons true. Lorsque le premier paramètre est supérieur au second, nous renvoyons false une déclaration indiquant que l'échange est requis. Lorsque les deux paramètres First et Second ont la même valeur, nous renvoyons false indiquant qu'aucun échange n'est requis. Nous pouvons même retourner vrai, mais l'échange n'a aucun effet ici.

5.2 Comparer les prédicats - Trier par nombre de portées

Le deuxième prédicat est écrit pour effectuer le tri par ordre décroissant. Notez que la façon dont l'opérateur "<" and ">" est utilisé et dans quelle mesure il exécute la fonction de prédicat précédente qui effectue le tri dans l'ordre croissant. Le code du deuxième prédicat est donné ci-dessous :

//ListSort 04b: Predicate function to sort by
// NumberOf Employees - descending
bool Compare_TotEmps_Predicate_Desc(
	Department First, Department Next)
{
	//First Argument Stays First (Return true)
	if (First.GetNumberOfStaffs() > 
		Next.GetNumberOfStaffs()) 
		return true;

	//First Argument goes Next 
	//(Swap) (Return false)
	if (First.GetNumberOfStaffs() < 
		Next.GetNumberOfStaffs()) 
		return false;

	//a==b. First Argument Stays 
	//first (No need to Swap)
	return true;
}

D'ACCORD. Il est maintenant temps de créer la liste C++, d'y stocker les instances de Department et d'effectuer le tri via nos fonctions de prédicat. Allons de l'avant !

Prédicat de comparaison C++ en action

D'ACCORD. Tout d'abord, préparons la liste et imprimons-la sur la fenêtre de sortie de la console. Tout d'abord, nous avons utilisé notre fonction globale Add_ListElements() en passant la liste standard C++ en tant que paramètre. La fonction regroupe cinq départements identiques dans la liste transmise. Ensuite, nous fournissons la liste emballée de Department à la fonction globale Print_List() pour imprimer le contenu de la liste. Le code est ci-dessous :

//3.1 Create list and iterator
list theList;
Add_ListElements(theList);
Print_List(theList);

À ce stade, nous avons une liste standard C++ qui contient cinq objets Department. Ceci est montré dans l'image ci-dessous:

Objet de classe Department stocké en C++ Std.  liste

Objet de classe Department stocké en C++ Std. liste

Ensuite, nous trions les objets Department par leur ID. Pour trier le département par ID, nous passons la fonction Predicate Compare_IDS_Predicate_Asc à "trier()" méthode de la liste. Maintenant, la méthode de tri sait comment trier l'objet département. Il parcourt la liste C++ et utilise la fonction de prédicat Compare_IDS_Predicate_Asc pour décider de l'ordre entre les objets département côte à côte dans la liste. Après l'appel à Sort (), les départements dans les listes sont classés par ordre croissant par leurs ID de département, et nous imprimons la liste dans la fenêtre de sortie de la console.

De la même manière en utilisant la fonction de prédicat Compare_TotEmps_Predicate_Desc, nous appelons à nouveau la méthode sort(). Cette fois, la liste sera triée par nombre d'employés dans le département par ordre décroissant. L'extrait de code est ci-dessous :

//3.2 Sort the List by IDs
printf("\nSorting List By ID:\n");
theList.sort(Compare_IDS_Predicate_Asc);
Print_List(theList);

//3.3 Sort the List by Department
printf("\nSorting List By Number of Staffs\n");
theList.sort(Compare_TotEmps_Predicate_Desc);
Print_List(theList);

L'opération à deux tris est illustrée comme indiqué ci-dessous :

Objets C++ triés par prédicats de comparaison et fonction Std List Sort()

Objets C++ triés par prédicats de comparaison et fonction Std List Sort()

Le code complet Exemple - C++ List Sort() with Compare Predicates

//ListSort00: Required Includes
#include 
#include 
#include 
#include 
#include 

using namespace std;

//ListSort 01: Department class fot this Hub
class Department
{
private:
	//1.1: Private Members
	int m_DeptID;
	string m_DeptName;
	int m_NumberOfStaffs;

public:
	//1.2: Department Class Constructor
	Department(int id, string name, int total_emp)
	{
		m_DeptID = id;
		m_DeptName = name;
		m_NumberOfStaffs = total_emp;
	}

	//1.3: Getter Functions
	int GetDeptId() 
	{
		return m_DeptID;
	}

	int GetNumberOfStaffs()
	{
		return m_NumberOfStaffs;
	}

	//1.4: Print Content of the Department Class
	void Print_Department()
	{
		cout << "Department - " << m_DeptName << "  ID:"
			<< m_DeptID << ", Total Staffs - " 
			<< m_NumberOfStaffs << endl;
	}
};

//ListSort 02: Function to Push some values to List
void Add_ListElements(list& listParam)
{
	//2.1: Clear the List
	listParam.clear();

	//2.2: Create Department Objects
	const Department D1(3, "Civil           ", 20);
	const Department D2(1, "Mechanical      ", 60);
	const Department D3(5, "Electrical      ", 22);
	const Department D4(4, "Chemical        ", 34);
	const Department D5(2, "Computer Science", 35);

	//2.3: Add Department Objects to List
	listParam.push_back(D1);
	listParam.push_back(D2);
	listParam.push_back(D3);
	listParam.push_back(D4);
	listParam.push_back(D5);
}

//ListSort 03: Function to Print the Values in List
void Print_List(list listParam)
{
	list::iterator listItr;
	printf("\nThe contents of the Lists are:\n");
	for (listItr = listParam.begin();
		listItr != listParam.end();
		listItr++)
	{
		(*listItr).Print_Department();
	}
}

//ListSort 04a: Predicate function to sory by 
// Department IDs in Ascending order
bool Compare_IDS_Predicate_Asc(
	Department First, Department Next)
{
	//First Argument Stays First (Return true)
	if (First.GetDeptId() < Next.GetDeptId()) 
		return true; 

	//First Argument goes Next (Swap) (Return false)
	if (First.GetDeptId() > Next.GetDeptId()) 
		return false;

	//a==b. First Argument Stays first 
	//(No need to Swap)
	return true;
}

//ListSort 04b: Predicate function to sort by
// NumberOf Employees - descending
bool Compare_TotEmps_Predicate_Desc(
	Department First, Department Next)
{
	//First Argument Stays First (Return true)
	if (First.GetNumberOfStaffs() > 
		Next.GetNumberOfStaffs()) 
		return true;

	//First Argument goes Next 
	//(Swap) (Return false)
	if (First.GetNumberOfStaffs() < 
		Next.GetNumberOfStaffs()) 
		return false;

	//a==b. First Argument Stays 
	//first (No need to Swap)
	return true;
}

//ListSort 05: Let go Sort the Department List
void main()
{
	//3.1 Create list and iterator
	list theList;
	Add_ListElements(theList);
	Print_List(theList); 

	//3.2 Sort the List by IDs
	printf("\nSorting List By ID:\n");
	theList.sort(Compare_IDS_Predicate_Asc);
	Print_List(theList);

	//3.3 Sort the List by Department
	printf("\nSorting List By Number of Staffs\n");
	theList.sort(Compare_TotEmps_Predicate_Desc);
	Print_List(theList);

	_getch();
}

La sortie du résultat du programme est illustrée ci-dessous :

Liste Trier Comparer Prédicat Exemple de sortie

Liste Trier Comparer Prédicat Exemple de sortie

Cet article est exact et fidèle au meilleur de la connaissance de l'auteur. Le contenu est uniquement à des fins d'information ou de divertissement et ne remplace pas un conseil personnel ou un conseil professionnel en matière commerciale, financière, juridique ou technique.

© 2018 sirama

Bouton retour en haut de la page