Insertion dans un set à l'aide d'itérateurs

Résolu/Fermé
Kumba - Modifié par baladur13 le 4/06/2016 à 10:55
 Kumba - 4 juin 2016 à 22:42
Bonjour à tous et à toutes !

Je suis actuellement en plein milieu d'un programme, dans lequel je dois insérer un objet (pointé par un itérateur) dans un set. Seulement, si j'ai réussi dans une autre fonction, ma tentative déclenche ici une salve d'erreurs
Mon code ressemble à ça

Une partie de mon .hh
#include <string>
#include <set>
#include <iostream>
#include <iterator>
//#include <algorithm>

using namespace std;

const std::string NO_ROUTE = "Error: No route!";
const std::string NO_SUCH_STOP = "Error: No such stop!";

struct Route
{
    int id;
    std::string name;
    set<struct Stop> stops;
    set<int> horaires;
};

struct Bus
{
    int id;
    int route_id;
    int driving_time;
};

struct Stop
{
    int id;
    std::string name;
    set<struct Route> routes;
};

inline bool operator< (const struct Route a, const struct Route b)
{
    return (a.id < b.id);
}

inline bool operator< (const struct Bus a, const struct Bus b)
{
    return (a.id < b.id);
}

inline bool operator< (const struct Stop a, const struct Stop b)
{
    return (a.id < b.id);
}

class Datastructure
{

    set<struct Bus> buses;
    set<struct Route> routes;
    set<struct Stop> stops;
}



La fonction qui bug dans le .cc

void Datastructure::add_stop_to_route(int route_id, int stop_id, unsigned int minutes)
{
    std::set<Stop>::iterator i;
    std::set<Route>::iterator j;
    //iterator
    //parcourir set des stops
    for (i = stops.begin(); i != stops.end() && i->id != stop_id; i++)
    {}
    if (i == stops.end())
        cout << NO_SUCH_STOP << endl;
    else
    {
        //iterator
        //parcourir set des routes
        for (j = routes.begin(); j != routes.end() && j->id != route_id; j++)
        {}
        if (j == routes.end())
            cout << NO_ROUTE << endl;
        else
        {
           j-> stops.insert(*i);
        }
    }
}


En fait le problème vient du
 j->stops.insert(*i) 
, mais je ne sais pas trop si j'utilise mal la fonction et ce qu'il faut que je change

Merci à tous et à toutes !

Kumba
EDIT : Ajout des balises de code (la coloration syntaxique).
Explications disponibles ici : ICI

Merci d'y penser dans tes prochains messages.
A voir également:

2 réponses

Dalfab Messages postés 706 Date d'inscription dimanche 7 février 2016 Statut Membre Dernière intervention 2 novembre 2023 101
3 juin 2016 à 23:44
Bonjour,

On ne peut pas modifier directement un élément d'un set<>, si on pouvait faire cela, le set<> ne pourrait pas garantir que les éléments sont toujours triés.
Ici j itère dans un set<> donc j->stops est constant.
Les set<> ne sont vraiment pas fait pour des objets qui varient.
Dans une map<> la clef qui permet le tri est disjointe de l'objet, on peut modifier les objets; dans la plupart des autres collections aussi, mais pas dans un set<>.
0
D'accord je vois !
Donc si je veux faire une insertion dans un set<>, je devrais faire une autre fonction qui cherche sa place ? Mais il y a une chose qui me laisse perplexe, je réalise une insertion au début de l’exécution qui sert à remplir tous mes set<>, celle ci marche parfaitement ?

Le mieux serait que je passe sur une map<> qui les garderait triés ? Y a-t-il beaucoup de différences d'implémentation entre les deux, dois-je modifier la façon dont j'ai tout codé ?

Merci encore !
0
Dalfab Messages postés 706 Date d'inscription dimanche 7 février 2016 Statut Membre Dernière intervention 2 novembre 2023 101 > Kumba
Modifié par Dalfab le 4/06/2016 à 07:38
L'intérêt d'un set est un accès très rapide en recherche, et de garantir une unicité de ses éléments.
Le set comme le map n'est absolument pas adapté aux parcours, hors le code en exemple ne fait que des parcours de recherche sans utiliser le fait qu'il sont triés.

Et la structure me parait avoir un fonctionnement curieux, quand on fait un insert() d'un stop trouvé, on crée un clone qui a le même 'id' mais les 2 stops évoluerons indépendamment l'un de l'autre.
Il faut bien distinguer les relations d'inclusions des relations de liens.
Est-ce qu'un stop contient un ensemble de routes?
Est-ce qu'une route contient un ensemble de stops?
Si les deux sont vrais, on ne peut pas avoir MonStop dans MaRoute dans MonStop, cela serait une boucle infinie.

void Datastructure::add_stop_to_route(int route_id, int stop_id, unsigned int minutes)
{
    // trouver le stop
    std::map<Stop>::iterator i = stops.find(stop_id);
    if ( i == stops.end() )
        cout << NO_SUCH_STOP << endl;
    else
    {
        // trouver la route
        std::map<Route>::iterator j = routes.find(route_id);
        if ( j == routes.end() )
            cout << NO_ROUTE << endl;
        else
        {
           j-> stops.insert( *i ); // création d'une copie du stop et donc des routes qu'il contient et donc des stops qu'elles contiennent et donc ...
        }
    }
}
Je pense qu'il donc plutôt des pointeurs etqu'il faut éviter plur le moment les objets tels que les set ou les map.
0
Kumba > Dalfab Messages postés 706 Date d'inscription dimanche 7 février 2016 Statut Membre Dernière intervention 2 novembre 2023
4 juin 2016 à 10:52
Ah d'accord !
Je n'avais pas pensé à la boucle infinie
En fait j'ai besoin de les garder triés, mais ce serait probablement plus simple avec des pointeurs, effectivement, merci beaucoup
0
Dalfab Messages postés 706 Date d'inscription dimanche 7 février 2016 Statut Membre Dernière intervention 2 novembre 2023 101
4 juin 2016 à 12:47
La structure que je vois par reverse sur tes données.
  • Un arrêt peut être sur plusieurs routes et a un nom.
  • Une route est composée d'arrêts, chaque arrêt y est caractérisé par un horaire.
  • Un car parcours une route.
  • Plusieurs cars peuvent parcourir une même route.


Un exemple avec des relations d'inclusion et de désignations (il y a des pointeurs mais jamais d'allocation dynamique)
struct Stop {
   std::string name;
};
struct Section {
   Stop* pstop;          // 'designe' l'arret a la fin du troncon
   unsigned horaire;
   class Route *proute;  // 'designe' la route qui utilise ce troncon
};
class Route {
public:
   void addStop( Stop* pstop , unsigned int minutes ) {
      remStop(pstop); // s'assurer que ce stop n'est qu'une fois sur la route
      sections.emplace_back( pstop , minutes , this );
   }
   void remStop( Stop* pstop ) {
      for ( auto isect = sections.begin() ; isect != sections.end() ; ) {
         if ( isect->pstop == pstop )
            isect = sections.erase( isect );
         else
            ++isect;
      } 
   }
   std::string name;
   std::vector<Sections> sections; // 'contient' des troncons 'ordonnes' qui 'utilisent' des arrets
};
class Bus {
public:
   setRoute( Route* proute ) {
      this->proute = proute;
      driving_time = 0;
      if ( proute )
         for ( Section const& section : proute->sections )
            driving_time += section.minutes;
   }
   int id;
   Route* proute = 0;
   int driving_time = 0;
};
class DataStructure {
public:
   void addStopToRoute(Route* proute, Stop* pstop, unsigned minutes) {
      proute->addStop( pstop , minutes );
   }
   std::vector<Route> theRoutes;
   std::vector<Stops> theStops;
   std::vector<Bus>   theBuses;
};
0
Ah d'accord je vois à peu près !

Merci beaucoup du coup, je vais essayer de régler tout ça ! :)
0