Projet tutoré 3 - Graphes
CGraphe.cpp
Aller à la documentation de ce fichier.
1 /*!
2  * \file CGraphe.cpp
3  * \brief Fichier contenant l'implémentation de la classe CGraphe
4  * \author Guillaume ELAMBERT
5  * \author Clément NONCHER-GILLET
6  * \date 2021
7  */
8 
9 
10 #include "CGraphe.h"
11 
12 
13 /*!
14  * Constructeur par défaut
15  *
16  */
18 {
19  pSOMGPHListeSommet = NULL;
20  uGPHTailleLSom = 0;
21 }
22 
23 
24 /*!
25  * Constructeur de recopie
26  *
27  * \param GPHParam L'objet CGraphe à copier
28  */
30 
31  *this = GPHParam;
32 }
33 
34 
35 /*!
36  * Constructeur de confort
37  * Création d'un graphe correctement initialisé à partir d'une chaîne de caractère OU un chemin vers un fichier contenant la chaîne de caractères.
38  * OU Une erreur si contenu est mal formatté ou qu'il contient des incohérences ou des erreurs.
39  *
40  * \param cpContenu La chaîne de caractère utilisée pour initialiser l'objet CGraphe
41  * \param bContenuEstChemin Un booléen qui indique si la variable cpContenu correspond à un chemin vers un fichier contenant l'initialisation d'un CGraphe (true) ou s'il s'agit directement d'une chaîne de caractère d'initialisation
42  */
43 CGraphe::CGraphe(const char *cpContenu, bool bContenuEstChemin)
44 {
45  if (cpContenu) {
46  char *cpContentToUse;
47 
48  //Entrée : La variable cpContenu correspond au chemin vers un fichier
49  // => On ouvre le fichier et on utilise le contenu pour l'initialisation
50  if (bContenuEstChemin) {
51  std::string sFileContent(""), sBuffer;
52  std::fstream FILfichier(cpContenu);
53  char sExceptionMessage[255];
54 
55  //Entrée : Le fichier à pu être ouvert
56  //Sinon : On renvoie une erreur
57  if (FILfichier.is_open())
58  {
59  while (std::getline(FILfichier, sBuffer)) {
60  //On concatène la ligne courrante avec les lignes précédentes
61  //On ajoute on retour à la ligne si la ligne courrante n'est pas la dernière du fichier
62  sFileContent += sBuffer + (!FILfichier.eof() ? "\n" : "");
63  }
64 
65  FILfichier.close();
66  cpContentToUse = _strdup(sFileContent.c_str());
67 
68  }
69  else {
70  FILfichier.close();
71  sprintf_s(sExceptionMessage, 255, "CGraphe::CGraphe(const char *cpChemin) : Impossible d'ouvrir le fichier \"%s\"\n", cpContenu);
72  throw CException(CGRAPHE_Ouverture_Fichier_Impossible, sExceptionMessage);
73  }
74 
75  }
76  else {
77  cpContentToUse = _strdup(cpContenu);
78  }
79 
80  //Initialisation par défaut
81  pSOMGPHListeSommet = NULL;
82  uGPHTailleLSom = 0;
83 
84  char sExceptionMessage[255];
85 
86  std::string sRegexResult;
87  std::regex rRegex("NBSommets[ \\t]*=[ \\t]*([0-9]+)[ \\t]*\\nNBArcs[ \\t]*=[ \\t]*([0-9]+)[ \\t]*\\nSommets[ \\t]*=[ \\t]*(\\[)[ \\t]*\\n((?:Numero[ \\t]*=[ \\t]*[0-9]+\\n)*)\\][ \\t]*\\nArcs[ \\t]*=[ \\t]*(\\[)[ \\t]*\\n((?:Debut[ \\t]*=[ \\t]*[0-9]+[ \\t]*,[ \\t]*Fin[ \\t]*=[ \\t]*([0-9]+)[ \\t]*\\n)*)\\]\\s*");
88  std::cmatch cmMatchGlobal, cmMatchNumeric;
89 
90  int iNbSommets, iNbArcs;
91  int iNbInit = 0;
92 
93  std::regex rNumericRegex("[0-9]+");
94 
95  //Entrée : Le fichier correspond à l'expression régulière
96  //Sinon : On renvoie une erreur
97  if (std::regex_match(cpContentToUse, cmMatchGlobal, rRegex)) {
98 
99  //On parcourt l'ensemble des résultats des groupes de capture du fichier (cf. la variable regex rRegex)
100  for (unsigned uiRegexIndex = 1; uiRegexIndex < cmMatchGlobal.size(); ++uiRegexIndex) {
101  sRegexResult = cmMatchGlobal[uiRegexIndex].str();
102 
103  //On vérifie si la ligne suivante est une initialisation du contenu
104  switch (sRegexResult[sRegexResult.length() - 1]) {
105  case '[':
106 
107  ++iNbInit;
108 
109  //Entrée : Il y a bien un résultat de la recherche regex après celui courrant
110  //Vérification normalement inutile car regex_match a renvoyé true
111  if (++uiRegexIndex < cmMatchGlobal.size()) {
112 
113  sRegexResult = cmMatchGlobal[uiRegexIndex].str();
114 
115  int iCurrentResIndex = 0, iResValue, iTempInitValue;
116 
117  //On parcourt la zone d'initialisation
118  while (std::regex_search(sRegexResult.c_str(), cmMatchNumeric, rNumericRegex)) {
119 
120  //On récupère la valeur du sommet/de l'arc
121  iResValue = atoi(cmMatchNumeric.str().c_str());
122 
123  //Entrée : On est dans la partie d'initialisation des sommets
124  // => On ajoute le sommet
125  if (iNbInit == 1) {
126  try {
127  this->GPHAjouterSommet(iResValue);
128  }
129  catch (CException EXCELevee) {
130  std::cerr << EXCELevee.EXCGetMessage();
131  }
132  }
133  //Entrée : On est dans la partie d'initialisation des arcs
134  else {
135  //Entrée : On est sur un idex pair (càd on est sur un début)
136  // => On stock la valeur pour la réutiliser quand on sera sur une fin de l'arc
137  if (iCurrentResIndex % 2 == 0) {
138  iTempInitValue = iResValue;
139  }
140  else {
141  try {
142  //On relie les deux sommets
143  this->GPHLierSommets(iTempInitValue, iResValue);
144  }
145  catch (CException EXCELevee) {
146  std::cerr << EXCELevee.EXCGetMessage();
147  }
148  }
149  }
150 
151  //On passe à la suite de la chaîne
152  sRegexResult = cmMatchNumeric.suffix();
153  ++iCurrentResIndex;
154  }
155 
156  //Entrée : le nombre de sommets définit est différent que celui trouvé
157  // => on renvoie une erreur
158  if (iNbInit == 1 && iCurrentResIndex != iNbSommets) {
159  sprintf_s(sExceptionMessage, 255, "CGraphe::CGraphe(const char *cpContenu, bool bContenuEstChemin) : %d sommets attendus %d sommets obtenus\n", iNbSommets, iCurrentResIndex);
160  throw CException(CGRAPHE_Erreur_NbArcs, sExceptionMessage);
161  }
162 
163  //Entrée : le nombre d'arcs définit est différent que celui trouvé
164  // => On renvoie une erreur
165  else if (iNbInit == 2 && (iCurrentResIndex /= 2) != iNbArcs) {
166  sprintf_s(sExceptionMessage, 255, "CGraphe::CGraphe(const char *cpContenu, bool bContenuEstChemin) : %d arcs attendus %d arcs obtenus\n", iNbArcs, iCurrentResIndex);
167  throw CException(CGRAPHE_Erreur_NbArcs, sExceptionMessage);
168  }
169  }
170 
171  break;
172 
173  default:
174  switch (uiRegexIndex) {
175 
176  case 1:
177  //printf("Le nombre de sommets est de : %s\n", sRegexResult.c_str());
178  iNbSommets = atoi(sRegexResult.c_str());
179  break;
180 
181  case 2:
182  //printf("Le nombre d'arcs est de : %s\n", sRegexResult.c_str());
183  iNbArcs = atoi(sRegexResult.c_str());
184 
185  //Entrée : On a défini un nombre de sommets à 0 pourtant on à defini des arcs
186  // => On renvoie une erreur
187  if (iNbSommets == 0 && iNbArcs != 0) {
188  throw CException(CGRAPHE_Erreur_NbArcs, "CGraphe::CGraphe(const char *cpContenu, bool bContenuEstChemin) : Le nombre de sommets a été défini sur 0, le nombre d'arcs devrait l'être aussi.\n");
189  }
190 
191 
192  //Entrée : On a dépasser le nombre de possibilité totale de laision entre les sommets
193  // => On renvoie une erreur
194  if (iNbArcs > (iNbSommets * iNbSommets - iNbSommets)) {
195  sprintf_s(sExceptionMessage, 255, "CGraphe::CGraphe(const char *cpContenu, bool bContenuEstChemin) : Top d'arcs a initialiser, %d maximum .\n", (iNbSommets * iNbSommets - iNbSommets));
196  throw CException(CGRAPHE_Erreur_NbArcs, sExceptionMessage);
197  }
198 
199  break;
200  }
201  break;
202  }
203  }
204  free(cpContentToUse);
205  }
206  else {
207  throw CException(CGRAPHE_Erreur_Syntaxe, "CGraphe::CGraphe(const char *cpContenu, bool bContenuEstChemin) : La chaîne de caractères ne correspond pas au format attendu\n");
208  }
209  }
210  else {
211  throw CException(CGRAPHE_Erreur_Syntaxe, "CGraphe::CGraphe(const char *cpContenu, bool bContenuEstChemin) : La chaîne de caractères est nulle\n");
212  }
213 }
214 
215 
216 /*!
217  * Destructeur par défaut
218  *
219  */
221 {
223 }
224 
225 
226 
227 /*!
228  * Cherche si le sommet existe
229  *
230  * \param uId Un numero de sommet
231  * \return L'index du sommet cherché
232  */
233 int CGraphe::GPHChercherSommet(unsigned int uId)
234 {
235  unsigned int uBoucle;
236  for (uBoucle = 0; uBoucle < uGPHTailleLSom; uBoucle++) {
237  if (pSOMGPHListeSommet[uBoucle]->SOMGetId() == uId) {
238  return(uBoucle);
239  }
240  }
241  return -1;
242 }
243 
244 
245 /*!
246  * Ajoute un nouveau sommet dans le graphe.
247  * OU renvoie une erreur si le sommet existe déjà
248  *
249  * \param uNumero Le numéro du nouveau sommet charché.
250  * \return L'index du sommet créé
251  */
252 unsigned int CGraphe::GPHAjouterSommet(unsigned int uNumero)
253 {
254 
255  //Entrée : Le sommet existe déjà dans le graphe
256  // => On renvoie une erreurs
257  if (GPHChercherSommet(uNumero) != -1) {
258  char sExceptionMessage[255];
259  sprintf_s(sExceptionMessage, 255, "CGraphe::GPHAjouterSommet(unsigned int uNumero) : Le sommet numero %d existe deja.\n", uNumero);
260  throw CException(CGRAPHE_Sommet_Existant, sExceptionMessage);
261  }
262 
263 
264  //Nouveau tableau à assigner à pSOMGPHListeSommet
265  CSommet ** pSOMNouvelleListe = (CSommet **) realloc(pSOMGPHListeSommet, sizeof(CSommet *)*(uGPHTailleLSom + 1));
266 
267  //Erreur si allocation échouée
268  if (pSOMNouvelleListe == NULL) {
269  throw(CException(CGRAPHE_Alloc_Echouee, "CGraphe::GPHAjouterSommet(unsigned int uNumero) : Erreur d'allocation/réallocation.\n"));
270  }
271 
272  //On ajoute le nouveau sommet
273  pSOMNouvelleListe[uGPHTailleLSom] = new CSommet(uNumero);
274  pSOMGPHListeSommet = pSOMNouvelleListe;
275 
276  uGPHTailleLSom++;
277  return uGPHTailleLSom - 1;
278 }
279 
280 
281 /*!
282  * Supprime un sommet dans le graphe.
283  * Supprime le sommet de numero uId du graphe ainsi que tout ses liens avec les autres sommets.
284  * OU renvoie une erreur si le sommet n'existe pas
285  *
286  * \param uId Numéro du sommet à supprimer
287  */
288 void CGraphe::GPHSupprimerSommet(unsigned int uId)
289 {
290  int iPos = GPHChercherSommet(uId);
291 
292  //Entrée : le sommet cherché existe
293  if (iPos != -1) {
294 
295  //On supprime tous les arcs (arrivants et partant) du sommet
296  for (unsigned uBoucle = 0; uBoucle < uGPHTailleLSom; uBoucle++) {
297  try {
298  GPHDelierSommets(uId, uBoucle);
299  GPHDelierSommets(uBoucle, uId);
300  }
301  catch (CException EXCELevee) {
302  std::cerr << EXCELevee.EXCGetMessage();
303  }
304  }
305 
306  CSommet ** pSOMNouvelleListe = (CSommet **) malloc(sizeof(CSommet *)*(uGPHTailleLSom - 1));
307 
308 
309  //Erreur si allocation échouée
310  if (pSOMNouvelleListe == NULL) {
311  throw(CException(CGRAPHE_Alloc_Echouee, "CGraphe::GPHSupprimerSommet(unsigned int uId) : Erreur d'allocation.\n"));
312  }
313 
314  //On copie tous les autres sommets dans un nouveau tableau
315  for (unsigned uBoucle = 0, uCounter = 0; uBoucle < uGPHTailleLSom; uBoucle++) {
316 
317  //Ajoute le sommet dans la nouvelle liste s'il ce n'est pas celui à supprimer
318  if (pSOMGPHListeSommet[uBoucle]->SOMGetId() != uId) {
319  pSOMNouvelleListe[uCounter] = pSOMGPHListeSommet[uBoucle];
320  uCounter++;
321  }
322  else {
323  delete pSOMNouvelleListe[uCounter];
324  }
325  }
326 
327  //On supprime l'ancien tableau et on lui assigne le nouveau
328  free(pSOMGPHListeSommet);
329  pSOMGPHListeSommet = pSOMNouvelleListe;
330 
331  uGPHTailleLSom--;
332  }
333 }
334 
335 
336 /*!
337  * Vérifie si deux sommets sont liés dans le sens sommet n° uSommetDep vers sommet n° uSommetArr
338  *
339  * \param uSommetDep Le sommet de départ
340  * \param uSommetArr Le sommet d'arrivé
341  * \return true si les deux sommets sons liés dans le sens sommet n° uSommetDep vers sommet n° uSommetArr false sinon
342  */
343 bool CGraphe::GPHLiees(unsigned int uSommetDep, unsigned int uSommetArr)
344 {
345  //Entrée : les deux sommets existent dans le graphe
346  if (GPHChercherSommet(uSommetDep) != -1 && GPHChercherSommet(uSommetArr) != -1) {
347  //On renvoie true s'ils sont liés, false sinon
348  return(pSOMGPHListeSommet[GPHChercherSommet(uSommetDep)]->SOMLies(*pSOMGPHListeSommet[GPHChercherSommet(uSommetArr)]));
349  }
350 
351  return false;
352 }
353 
354 
355 /*!
356  * Lie deux sommets du graphe (créé l'arc Sommet de n° uIdDepart vers Sommet de n° uIdArrivee).
357  * OU renvoie une erreur s'il existe déjà un arc dirigé entre les deux sommets (càd de Sommet de n° uIdDepart vers Sommet de n° uIdArrivee)
358  *
359  * \param uIdDepart Le numéro du sommet de départ
360  * \param uIdArrivee Le numéro du sommet d'arrivé
361  */
362 void CGraphe::GPHLierSommets(unsigned int uIdDepart, unsigned int uIdArrivee)
363 {
364  char sExceptionMessage[255];
365 
366  //Entrée : Pas de tentative de relier un sommet avec lui-même
367  //Sinon : On renvoie une erreur
368  if (uIdDepart != uIdArrivee) {
369  int iPosDep;
370  int iPosArr = GPHChercherSommet(uIdArrivee);
371 
372  //Entrée : Le sommet d'arrivée existe dans le graphe
373  //Sinon : On renvoie une erreur
374  if (iPosArr != -1)
375  {
376  iPosDep = GPHChercherSommet(uIdDepart);
377 
378  //Le sommet de départ existe dans le graphe
379  //Sinon : On renvoie une erreur
380  if (iPosDep != -1) {
381 
382  //Entrée : Il existe déjà un arc dans le sens Sommet de n° uIdDepart vers Sommet de n° uIdArrivee
383  // => On renvoie une erreur
384  if (pSOMGPHListeSommet[iPosDep]->SOMChercherArcSortant(uIdArrivee) != -1) {
385  sprintf_s(sExceptionMessage, 255, "CGraphe::GPHLierSommets(unsigned int uIdDepart, unsigned int uIdArrivee) : L'arc sortant depuis %d vers %d existe deja.\n", uIdDepart, uIdArrivee);
386  throw CException(CGRAPHE_Arc_Existant, sExceptionMessage);
387  }
388 
389  try {
390  //On créé on arc de départ dans le sommet de départ et un d'arrivé dans le sommet d'arrivé
391  pSOMGPHListeSommet[iPosDep]->SOMAjouterArcSortant(uIdArrivee);
392  pSOMGPHListeSommet[iPosArr]->SOMAjouterArcArrivant(uIdDepart);
393  }
394  catch (CException EXCELevee) {
395  std::cerr << EXCELevee.EXCGetMessage();
396  }
397  }
398  else {
399  sprintf_s(sExceptionMessage, 255, "CGraphe::GPHLierSommets(unsigned int uIdDepart, unsigned int uIdArrivee) : Le sommet de depart %d est inconnu.\n", uIdDepart);
400  throw CException(CGRAPHE_Sommet_Inconnu, sExceptionMessage);
401  }
402  }
403  else
404  {
405  sprintf_s(sExceptionMessage, 255, "CGraphe::GPHLierSommets(unsigned int uIdDepart, unsigned int uIdArrivee) : Le sommet d'arrivee %d est inconnu.\n", uIdArrivee);
406  throw CException(CGRAPHE_Sommet_Inconnu, sExceptionMessage);
407  }
408  }
409  else {
410  sprintf_s(sExceptionMessage, 255, "CGraphe::GPHLierSommets(unsigned int uIdDepart, unsigned int uIdArrivee) : Tentative de relier le sommet %d avec lui-meme.\n", uIdArrivee);
411  throw CException(CGRAPHE_Auto_Referencement, sExceptionMessage);
412  }
413 }
414 
415 
416 /*!
417  * Délie deux sommets du graphe (supprime l'arc Sommet de n° uIdDepart vers Sommet de n° uIdArrivee).
418  * OU renvoie une erreur si l'arc n'existe pas
419  *
420  * \param uIdDepart Le numéro du sommet de départ
421  * \param uIdArrivee Le numéro du sommet d'arrivé
422  */
423 void CGraphe::GPHDelierSommets(unsigned int uIdDepart, unsigned int uIdArrivee)
424 {
425  int iPosDep;
426  int iPosArr = GPHChercherSommet(uIdArrivee);
427 
428 
429  char sExceptionMessage[255];
430 
431  //Entrée : le sommet d'arrivé existe dans le graphe
432  //Sinon : On renvoie une erreur
433  if (iPosArr != -1){
434 
435  iPosDep = GPHChercherSommet(uIdDepart);
436 
437  //Entrée : le sommet de départ existe dans le graphe
438  //Sinon : On renvoie une erreur
439  if (iPosDep != -1) {
440 
441  //Entrée : Les sommets sont bien liés par un arc dans le sens Sommet de n° uIdDepart vers Sommet de n° uIdArrivee
442  if (pSOMGPHListeSommet[iPosDep]->SOMLies(*pSOMGPHListeSommet[iPosArr]) == true) {
443 
444  try {
445  //On créé on arc de départ dans le sommet de départ et un d'arrivé dans le sommet d'arrivé
446  pSOMGPHListeSommet[iPosDep]->SOMRetirerArcSortant(uIdArrivee);
447  pSOMGPHListeSommet[iPosArr]->SOMRetirerArcArrivant(uIdDepart);
448  }
449  catch (CException EXCELevee) {
450  std::cerr << EXCELevee.EXCGetMessage();
451  }
452  }
453  }
454  else {
455  sprintf_s(sExceptionMessage, 255, "CGraphe::GPHDelierSommets(unsigned int uIdDepart, unsigned int uIdArrivee) : Le sommet de depart %d est inconnu.\n", uIdDepart);
456  throw CException(CGRAPHE_Sommet_Inconnu, sExceptionMessage);
457  }
458  }
459  else
460  {
461  sprintf_s(sExceptionMessage, 255, "CGraphe::GPHDelierSommets(unsigned int uIdDepart, unsigned int uIdArrivee) : Le sommet d'arrivee %d est inconnu.\n", uIdArrivee);
462  throw CException(CGRAPHE_Sommet_Inconnu, sExceptionMessage);
463  }
464 }
465 
466 
467 /*!
468  * Renvoie les numéros des arcs sortants d'un sommet.
469  *
470  * \param uId Le numero du sommet dont on veut les arcs sortants
471  * \return Un tableau d'entiers contenant les arcs sortant et en première position le nombre d'éléments scannés.
472  */
473 unsigned int * CGraphe::GPHLireArcsS(unsigned int uId)
474 {
475  int iPos = GPHChercherSommet(uId);
476 
477  //Entrée : Le sommet n'existe pas dans le graphe
478  if (iPos == -1) {
479  return nullptr;
480  }
481 
482  //Entrée : Le sommet n'a pas d'arcs sortants
483  if (pSOMGPHListeSommet[iPos]->SOMGetTailleS() == 0) {
484  return nullptr;
485  }
486 
487  unsigned int uBoucle;
488  unsigned int * puTableau = new unsigned int[pSOMGPHListeSommet[iPos]->SOMGetTailleS() + 1];
489 
490  //On parcourt tous les arcs sortants du sommet et on les met dans le tableau à retourner
491  for (uBoucle = 1; uBoucle < pSOMGPHListeSommet[iPos]->SOMGetTailleS() + 1; uBoucle++) {
492  try {
493  puTableau[uBoucle] = pSOMGPHListeSommet[iPos]->SOMLireListeS(uBoucle)->ARCGetDestination();
494  }
495  catch (CException EXCELevee) {
496  std::cerr << EXCELevee.EXCGetMessage();
497  }
498  }
499 
500  //On stock à l'indice 0 le nombre d'arcs dans le tableau à retourner
501  puTableau[0] = pSOMGPHListeSommet[iPos]->SOMGetTailleS();
502  return puTableau;
503 }
504 
505 
506 /*!
507  * Renvoie les numéros des arcs arrivants d'un sommet.
508  *
509  * \param uId Le numero du sommet dont on veut les arcs arrivants
510  * \return Un tableau d'entiers contenant les arcs arrivants et en première position le nombre d'éléments scannés.
511  */
512 unsigned int * CGraphe::GPHLireArcsA(unsigned int uId)
513 {
514  int iPos = GPHChercherSommet(uId);
515 
516  //Entrée : Le sommet n'existe pas dans le graphe
517  if (iPos == -1) {
518  return nullptr;
519  }
520 
521  //Entrée : Le sommet n'a pas d'arcs arrivants
522  if (pSOMGPHListeSommet[iPos]->SOMGetTailleA() == 0) {
523  return nullptr;
524  }
525 
526  unsigned int uBoucle;
527  unsigned int * puTableau = new unsigned int[pSOMGPHListeSommet[iPos]->SOMGetTailleA() + 1];
528 
529  //On parcourt tous les arcs arrivants du sommet et on les met dans le tableau à retourner
530  for (uBoucle = 1; uBoucle < pSOMGPHListeSommet[iPos]->SOMGetTailleA() + 1; uBoucle++) {
531  try {
532  puTableau[uBoucle] = pSOMGPHListeSommet[iPos]->SOMLireListeA(uBoucle)->ARCGetDestination();
533  }
534  catch (CException EXCELevee) {
535  std::cerr << EXCELevee.EXCGetMessage();
536  }
537  }
538 
539  //On stock à l'indice 0 le nombre d'arcs dans le tableau à retourner
540  puTableau[0] = pSOMGPHListeSommet[iPos]->SOMGetTailleA();
541  return puTableau;
542 }
543 
544 
545 /*!
546  * Affiche le sommet de numéro uId
547  *
548  * \param uId Le numéro du sommet à afficher
549  */
550 void CGraphe::GPHAfficherSommet(unsigned int uId)
551 {
552  int iPos = GPHChercherSommet(uId);
553 
554  //Entrée : Le sommet existe dans le graphe
555  //Sinon : On renvoie une erreur
556  if (iPos != -1) {
558  }
559  else {
560  char sExceptionMessage[255];
561  sprintf_s(sExceptionMessage, 255, "Le sommet %d n'est pas dans le graphe.\n", uId);
562  throw CException(CGRAPHE_Sommet_Inconnu, sExceptionMessage);
563  }
564 }
565 
566 
567 /*!
568  * Affiche le graphe
569  *
570  */
572 {
573  std::cout << "Nb sommets : " << uGPHTailleLSom << std::endl;
574  unsigned int uBoucle;
575 
576  //On affiche tous les sommets
577  for (uBoucle = 0; uBoucle < uGPHTailleLSom; uBoucle++) {
578  try {
580  }
581  catch (CException EXCELevee) {
582  std::cerr << EXCELevee.EXCGetMessage();
583  }
584  }
585  std::cout << std::endl;
586 }
587 
588 
589 /*!
590  * Inverse les arcs du graphe : les arcs sortants deviennent arrivants et vice-versa
591  *
592  * \return Un nouvel objet CGraphe, inversé par rapport à 'objet appelant
593  */
595  CGraphe * GPHGrapheRenv = new CGraphe(*this);
596  unsigned int uBoucle;
597 
598  //On inverse les arcs pour chaque sommet
599  for (uBoucle = 0; uBoucle < uGPHTailleLSom; uBoucle++) {
600  GPHGrapheRenv->pSOMGPHListeSommet[uBoucle]->SOMInverser();
601  }
602  return *GPHGrapheRenv;
603 }
604 
605 
606 /*!
607  * Surcharge de l'opérateur =
608  * Copie le contenu de GPHParam dans l'objet appelant
609  *
610  * \param GPHParam L'objet CGraphe à copier
611  * \return Un pointeur sur l'objet appelant, copie de GPHParam
612  */
614 {
615  if (this != &GPHParam) {
616  uGPHTailleLSom = GPHParam.uGPHTailleLSom;
617  //pSOMGPHListeSommet = new CSommet[GPHParam.uGPHTailleLSom];
618 
619  //On alloue la liste des sommets
620  if ( ( pSOMGPHListeSommet = (CSommet **) realloc(pSOMGPHListeSommet, sizeof(CSommet *) * (GPHParam.uGPHTailleLSom) ) ) == NULL ) {
621 
622  throw(CException(CGRAPHE_Alloc_Echouee, "CSommet::operator=(const CSommet & SOMParam) : Erreur d'allocation/réallocation.\n"));
623  }
624 
625  unsigned int uBoucle;
626 
627  //On copie la liste des sommets de GPHParam
628  for (uBoucle = 0; uBoucle < uGPHTailleLSom; uBoucle++) {
629  pSOMGPHListeSommet[uBoucle] = new CSommet(*GPHParam.pSOMGPHListeSommet[uBoucle]);
630  }
631  }
632 
633  return *this;
634 }
CGraphe::~CGraphe
~CGraphe(void)
Definition: CGraphe.cpp:220
CGraphe::CGraphe
CGraphe(void)
Definition: CGraphe.cpp:17
CArc::ARCGetDestination
unsigned int ARCGetDestination(void)
Definition: CArc.cpp:58
CGraphe::GPHLireArcsA
unsigned int * GPHLireArcsA(unsigned int uId)
Definition: CGraphe.cpp:512
CSommet::SOMAjouterArcArrivant
void SOMAjouterArcArrivant(unsigned int uDestination)
Definition: CSommet.cpp:122
CGraphe::GPHDelierSommets
void GPHDelierSommets(unsigned int uIdDepart, unsigned int uIdArrivee)
Definition: CGraphe.cpp:423
CGraphe::GPHLireArcsS
unsigned int * GPHLireArcsS(unsigned int uId)
Definition: CGraphe.cpp:473
CGraphe::GPHLiees
bool GPHLiees(unsigned int uSommetDep, unsigned int uSommetArr)
Definition: CGraphe.cpp:343
CGraphe::uGPHTailleLSom
unsigned int uGPHTailleLSom
Definition: CGraphe.h:45
CGraphe::GPHChercherSommet
int GPHChercherSommet(unsigned int uId)
Definition: CGraphe.cpp:233
CSommet::SOMRetirerArcArrivant
void SOMRetirerArcArrivant(unsigned int uDestination)
Definition: CSommet.cpp:147
CGraphe
Classe du graphe.
Definition: CGraphe.h:41
CGraphe::GPHAfficherGraphe
void GPHAfficherGraphe()
Definition: CGraphe.cpp:571
CSommet::SOMAjouterArcSortant
void SOMAjouterArcSortant(unsigned int uDestination)
Definition: CSommet.cpp:234
CGraphe::operator=
CGraphe & operator=(CGraphe &GPHParam)
Definition: CGraphe.cpp:613
CSommet::SOMInverser
void SOMInverser()
Definition: CSommet.cpp:383
CGraphe::GPHAfficherSommet
void GPHAfficherSommet(unsigned int uId)
Definition: CGraphe.cpp:550
CSommet::SOMGetTailleA
unsigned int SOMGetTailleA()
Definition: CSommet.cpp:99
CException
Classe d'exception personnalisée.
Definition: CException.h:25
CSommet::SOMLireListeA
CArc * SOMLireListeA(unsigned int uPos)
Definition: CSommet.cpp:213
CGraphe::GPHSupprimerSommet
void GPHSupprimerSommet(unsigned int uId)
Definition: CGraphe.cpp:288
CGraphe::GPHRenverserGraphe
CGraphe & GPHRenverserGraphe()
Definition: CGraphe.cpp:594
CException::EXCGetMessage
const char * EXCGetMessage(void)
Definition: CException.cpp:71
CSommet::SOMGetTailleS
unsigned int SOMGetTailleS()
Definition: CSommet.cpp:110
CGraphe::GPHLierSommets
void GPHLierSommets(unsigned int uIdDepart, unsigned int uIdArrivee)
Definition: CGraphe.cpp:362
CGraphe.h
Fichier contenant la déclaration de la classe CGraphe.
CSommet
Classe des sommets d'un graphe.
Definition: CSommet.h:29
CSommet::SOMAfficherSommet
void SOMAfficherSommet()
Definition: CSommet.cpp:405
CSommet::SOMRetirerArcSortant
void SOMRetirerArcSortant(unsigned int uDestination)
Definition: CSommet.cpp:261
CGraphe::GPHAjouterSommet
unsigned int GPHAjouterSommet(unsigned int uNumero)
Definition: CGraphe.cpp:252
CSommet::SOMLireListeS
CArc * SOMLireListeS(unsigned int uPos)
Definition: CSommet.cpp:325
CGraphe::pSOMGPHListeSommet
CSommet ** pSOMGPHListeSommet
Definition: CGraphe.h:44