IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SL & STL C++ Discussion :

Syncronisation de vecteurs


Sujet :

SL & STL C++

  1. #1
    Membre très actif
    Avatar de TheDrev
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2006
    Messages : 310
    Par défaut Syncronisation de vecteurs
    Bonjour, j'aimerai savoir comment synchroniser deux vecteurs de pointeurs.

    Voici un petit exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    #include <iostream>
    #include <vector>
     
    using namespace std;
     
    class Bidon
    {
    	public: 
    	Bidon(int Numero);
    	int Numero;
    };
     
    Bidon::Bidon(int Numero)
    {
    	this->Numero = Numero;
    }
     
    int main (void)
    {
    	int i;
    	Bidon *TempBidon;
    	vector <Bidon *>vecPremier;
    	vector <Bidon *>vecSecond;
     
    	//Ajout et syncronisation
    	for(i=0;i<5;i++){
    		vecPremier.push_back(TempBidon = new Bidon(i));		//ajout
    		vecSecond.push_back(vecPremier.back());				//Syncronistion
    	}
     
    	//Affichage du numero bidon et du pointeur des deux vecteurs
    	for(i=0;i<vecPremier.size();i++){
    		cout << "Premier : " << vecPremier.at(i)->Numero << " &"<< vecPremier.at(i) << " Second : " <<	vecSecond.at(i)->Numero << " &" << vecSecond.at(i) << endl;
    	}	
     
    	//Supprimer quelques instances dans le premier vecteur
    	vecPremier.erase(vecPremier.begin() + 2);
    	vecPremier.erase(vecPremier.begin() + 3);
     
    	cout << endl;
     
    	//Affichage du numero de bidon et du pointeur dans le premier vecteur 
    	for(i=0;i<vecPremier.size();i++){
    		cout << "Premier : " << vecPremier.at(i)->Numero << " &"<< vecPremier.at(i) << endl;
    	}	
     
    	cout << endl;
     
    	//Affichage du numero bidon et du pointeur dans le second  vecteur 
    	for(i=0;i<vecSecond.size();i++){
    		cout << "Second : " << vecSecond.at(i)->Numero << " &"<< vecSecond.at(i) << endl;
    	}	
    }

    Sortie :

    Premier : 0 &0x3d2450 Second : 0 &0x3d2450
    Premier : 1 &0x3d24d8 Second : 1 &0x3d24d8
    Premier : 2 &0x3d24c8 Second : 2 &0x3d24c8
    Premier : 3 &0x3d24b8 Second : 3 &0x3d24b8
    Premier : 4 &0x3d24e8 Second : 4 &0x3d24e8

    Premier : 0 &0x3d2450
    Premier : 1 &0x3d24d8
    Premier : 3 &0x3d24b8

    Second : 0 &0x3d2450
    Second : 1 &0x3d24d8
    Second : 2 &0x3d24c8
    Second : 3 &0x3d24b8
    Second : 4 &0x3d24e8
    _______________________________
    En finale, il faudrait que le second vecteur contienne
    Second : 0 &0x3d2450
    Second : 1 &0x3d24d8
    Second : 3 &0x3d24b8

    J'ai deja essaye en comparent les adresses, mais sur des applications plus grandes, elle peuvent évidement changer en cours de vérification !
    Mais comment faire ?

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Salut,

    Si tu ne supprimes pas les pointeurs du second vecteur, ça ne va pas se faire magiquement...

    Est-ce que ton problème ne serait pas plutôt de savoir comment organiser les choses pour qu'un seul 'module' (mettons une classe pour simplifier) soit responsable des éléments et que les autres 'modules' soient avertis quand de nouveaux éléments sont créés ou que certains sont supprimés ?

    MAT.

  3. #3
    Membre très actif
    Avatar de TheDrev
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2006
    Messages : 310
    Par défaut
    Salut,

    Je n 'ai pas mis mon code qui compare les pointeurs pour determiner lesquelles supprimer, car il est mauvais.

    Cependant tu as bien resumer mon probleme... j ai cherché sur le forum des solutions mais je n ai pas compris.

  4. #4
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Hmm en fait non j'avais sans doute mal compris ton problème...
    Est-ce que tu as regardé cette entrée de la FAQ ? Ça ne répond pas à ta question ?

    MAT.

  5. #5
    Membre très actif
    Avatar de TheDrev
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2006
    Messages : 310
    Par défaut
    Ceci ne répond qu' a moiter a mon problème.
    Je cherche effectivement a supprimer des element dans un vecteur, mais pas en fonction de la valeur (un int dans l exemple de la faq), mais en fonction du pointeur même.

    Ceci me permettra de supprimer des instances de classes qui n'ont plus lieu d'être dans un vecteur , puisque que leur clone (pointeur a la même adresse, dans un autre vecteur) à été supprimé.

    J'espère que je m'exprime correctement, sinon n' hésitez pas a me faire préciser certains points.

  6. #6
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Citation Envoyé par TheDrev Voir le message
    Je cherche effectivement a supprimer des element dans un vecteur, mais pas en fonction de la valeur (un int dans l exemple de la faq), mais en fonction du pointeur même.
    Dans la FAQ le vecteur stocke des int, dans ton code le vecteur stocke des Bidon* (donc des pointeurs sur Bidon). Tout ce qui est fait sur des entiers dans l'exemple de la FAQ est transposable pour des pointeurs sur Bidon dans ton cas.

    Fais voir à quoi ressemble ton code pour retirer un pointeur du vecteur (tu peux tout à fait t'inspirer de l'exemple de la FAQ pour l'écrire) ?

    MAT.

  7. #7
    Membre très actif
    Avatar de TheDrev
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2006
    Messages : 310
    Par défaut
    Salut,
    j'ai modifié mon code et j'ai ajouter un flag et deux boucles imbriquée pour tester les valeurs.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
     
    #include <iostream>
    #include <vector>
     
    using namespace std;
     
    class Bidon
    {
    	public: 
    	Bidon(int Numero);
    	int Numero;
    };
     
    Bidon::Bidon(int Numero)
    {
    	this->Numero = Numero;
    }
     
    int main (void)
    {
    	int i, j;
    	bool flagSupp;
    	Bidon *TempBidon;
    	vector <Bidon *>vecPremier;
    	vector <Bidon *>vecSecond;
     
    	//Ajout et syncronisation
    	for(i=0;i<5;i++){
    		vecPremier.push_back(TempBidon = new Bidon(i));		//ajout
    		vecSecond.push_back(vecPremier.back());				//Syncronisation
    	}
     
    	//Affichage du numero bidon et du pointeur des deux vecteurs
    	for(i=0;i<vecPremier.size();i++){
    		cout << "Premier : " << vecPremier.at(i)->Numero << " &"<< vecPremier.at(i) << " Second : " <<	vecSecond.at(i)->Numero << " &" << vecSecond.at(i) << endl;
    	}	
     
    	//Supprimer quelques instances dans le premier vecteur
    	cout << endl << "Suppression a l'index 2 &" << vecPremier.at(2) << " et 3 &" << vecPremier.at(3) << endl << endl;
    	vecPremier.erase(vecPremier.begin() + 2);
    	vecPremier.erase(vecPremier.begin() + 3);
     
    	//Affichage du numero de bidon et du pointeur dans le premier vecteur 
    	for(i=0;i<vecPremier.size();i++){
    		cout << "Premier : " << vecPremier.at(i)->Numero << " &"<< vecPremier.at(i) << endl;
    	}
     
    	cout << endl;
     
    	for (i=0;i<vecSecond.size();i++){
    		flagSupp = true;
    		j = 0;
    		cout << "vecSecond : Verification de " << i << endl;
    		do{
    			cout << vecSecond.at(i) << " == " << vecPremier.at(j) << " ? " <<  endl;
    			if ((vecSecond.at(i) == vecPremier.at(j))){
    				cout << "oui... garder cette instance" << endl << endl;
    				flagSupp = false;
    			}
    			j++;
    		}while(flagSupp && j<vecPremier.size());
     
    		if(flagSupp){
    			cout << "SUPPRESSION effectue a l'index : " << i << endl;
    			vecSecond.erase(vecSecond.begin()+i);
    		}
    	}
     
    	cout << endl;
     
    	//Affichage du numero bidon et du pointeur dans le second  vecteur 
    	for(i=0;i<vecSecond.size();i++){
    		cout << "Second : " << vecSecond.at(i)->Numero << " &"<< vecSecond.at(i) << endl;
    	}
    }
    Sortie :

    Premier : 0 &0x3d3f00 Second : 0 &0x3d3f00
    Premier : 1 &0x3d3fa0 Second : 1 &0x3d3fa0
    Premier : 2 &0x3d3f90 Second : 2 &0x3d3f90
    Premier : 3 &0x3d3f80 Second : 3 &0x3d3f80
    Premier : 4 &0x3d3fb0 Second : 4 &0x3d3fb0

    Suppression a l'index 2 &0x3d3f90 et 3 &0x3d3f80

    Premier : 0 &0x3d3f00
    Premier : 1 &0x3d3fa0
    Premier : 3 &0x3d3f80

    vecSecond : Verification de 0
    0x3d3f00 == 0x3d3f00 ?
    oui... garder cette instance

    vecSecond : Verification de 1
    0x3d3fa0 == 0x3d3f00 ?
    0x3d3fa0 == 0x3d3fa0 ?
    oui... garder cette instance

    vecSecond : Verification de 2
    0x3d3f90 == 0x3d3f00 ?
    0x3d3f90 == 0x3d3fa0 ?
    0x3d3f90 == 0x3d3f80 ?
    SUPPRESSION effectue a l'index : 2
    vecSecond : Verification de 3
    0x3d3fb0 == 0x3d3f00 ?
    0x3d3fb0 == 0x3d3fa0 ?
    0x3d3fb0 == 0x3d3f80 ?
    SUPPRESSION effectue a l'index : 3

    Second : 0 &0x3d3f00
    Second : 1 &0x3d3fa0
    Second : 3 &0x3d3f80
    ================================

    Comme tu le vois, le code fonctionne maintenant.
    Ma question serai maintenant :
    - Ce code est il sécurisé ?
    - Peut on faire la même chose avec la STL (avec un remove_if ? ) je début seulement avec <algorithme>
    - Existe il des motifs de conceptions pour gérer ce genre de problèmes de synchronisations (je pense que oui, mais je n'ai rien trouve de transcendant)

    Merci pour ta patience jusqu'à présent.

  8. #8
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Qu'est-ce que tu appelles sécurisé ?
    En tous cas ce code n'est sans doute pas beau

    Hors contexte c'est difficile de donner une solution puisque j'imagine que c'est pas vraiment le vrai code là si ?
    Sinon le plus simple est bien sûr de répercuter les mêmes suppressions sur vecSecond que sur vecPremier, comme tu le fais pour les ajouts...
    Sinon tu peux aussi écraser vecSecond avec vecPremier une fois les modifications faites...

    Dans tous les cas je ne suis pas sûr que ça soit très intéressant de chercher à "synchroniser".

    MAT.

  9. #9
    Membre très actif
    Avatar de TheDrev
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2006
    Messages : 310
    Par défaut
    Oui, ceci n'est heureusement qu'un exemple.
    Sauf la partie synchronisation en elle même.
    Je ne peut pas écraser un vecteur par un autre, car dans d'autres programmes il y a d'autres instances supplémentaire a conserver.

    Si je me pose ce genre de question, c'est par exemple pour implementer un diagramme UML avec partage d'instances...

    Par sécurisé, je veut signaler un éventuelle problème sur cette comparaison de pointeur sur cette ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ((vecSecond.at(i) == vecPremier.at(j))){
    Ce que je cherche mieux faire, c'est uniquement cette partie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    for (i=0;i<vecSecond.size();i++){
    		flagSupp = true;
    		j = 0;
    		cout << "vecSecond : Verification de " << i << endl;
    		do{
    			cout << vecSecond.at(i) << " == " << vecPremier.at(j) << " ? " <<  endl;
    			if ((vecSecond.at(i) == vecPremier.at(j))){
    				cout << "oui... garder cette instance" << endl << endl;
    				flagSupp = false;
    			}
    			j++;
    		}while(flagSupp && j<vecPremier.size());
     
    		if(flagSupp){
    			cout << "SUPPRESSION effectue a l'index : " << i << endl;
    			vecSecond.erase(vecSecond.begin()+i);
    		}
    	}
    Le terme synchroniser n'est peut être pas le meilleur, je cherche simplement à retirer les instances dans le second vecteur qui ont été préalablement retire dans le premier vecteur.

  10. #10
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Citation Envoyé par TheDrev Voir le message
    Par sécurisé, je veut signaler un éventuelle problème sur cette comparaison de pointeur sur cette ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ((vecSecond.at(i) == vecPremier.at(j))){
    Il n'y a pas de problème ça compare bien les éléments contenus dans les vecteurs, et donc les pointeurs.

    Sinon je ne vois vraiment pas de cas d'utilisation qui nécessiterait de faire une telle "synchronisation"...
    Le truc c'est qu'en amont de cet algorithme somme toute assez bas niveau, il y a de toute façon un mécanisme à mettre en place pour notifier les différents modules lorsqu'un changement a eu lieu (ajout ou suppression).
    Là en général de deux choses l'une :
    . soit on notifie des deltas, et donc on dit élément machin ajouté ou élément truc supprimé
    . soit on notifie le nouvel état, et donc ici le nouveau vecteur au complet dont on écrasera la copie locale sans vergogne

    Après si vraiment tu veux faire ce truc de synchronisation à bas niveau, il y a sans doute moyen de faire ça avec un remove_if, du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    namespace
    {
        bool contains( int value, const std::vector< Bidon* >* v )
        {
            return std::find( v->begin(), v->end(), value ) != v->end();
        }
    }
     
    ...
        vecSecond.erase( std::remove_if( vecSecond.begin(), vecSecond.end(), std::not1( std::bind2nd( ptr_fun( contains ), &vecPremier ) ) ), vecSecond.end() );
    (quelqu'un trouvera peut-être une meilleure écriture...)

    Mais est-ce bien raisonnable ? Je ne suis pas certain que ça en vaille réellement le coup comparé à un bête :
    En tous cas personnellement je commencerai pas ça (si ce n'est que j'ai l'habitude de faire des notifications à base de deltas en général mais bon) et si à un moment un problème (de performance) se révèle il sera toujours temps de réagir...

    MAT.

  11. #11
    Membre très actif
    Avatar de TheDrev
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2006
    Messages : 310
    Par défaut
    Okey merci pour ces réponses si rapide

    Je me sert de ces suppression dans quelques programmes dont il est probable que la conception même soit à revoir.

    Par exemple, je suis en train de porter un logiciel sur les graphes orientées du C au C++. Dans le programme C, il y a une structure graphe, qui contient un tableau de sommets, chaque sommet contient un tableau de chemin.
    Rien de spéciale ici, sauf que la structure graphe contient aussi un tableau de tout les chemins crées. Dans le programme C, il n'est pas possible de supprimer un élément. Mais dans le programme C++, je profite de vector de la STL. J ai fait l'erreur de garder la structure du programme en C... d'ou se besoin de synchronisation entre le vecteur chemin du graphe et le vecteur chemin d'un sommet devant etre supprimé !

    j'ai l'habitude de faire des notifications à base de deltas
    Qu'est se que c'est des notifications à base de deltas ?

  12. #12
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Citation Envoyé par TheDrev Voir le message
    Qu'est se que c'est des notifications à base de deltas ?
    Quand une donnée change et que tu as besoin d'en avertir d'autres modules, tu peux soit leur envoyer la totalité du nouvel état de la donnée, soit envoyer la différence qui permet de passer de l'état précédent à ce nouvel état.
    Suivant le type de donnée la seconde possibilité peut être plus intéressante, notamment pour un vecteur d'éléments puisqu'il s'agit alors des éléments ajoutés et supprimés entre les deux états.

    MAT.

  13. #13
    Membre très actif
    Avatar de TheDrev
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2006
    Messages : 310
    Par défaut
    Okey, j'en ai appris plus sur les vecteurs...
    je vais essayer de revoir tout ca.
    Thanks

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Utilisation des vecteurs
    Par EmilieG dans le forum MFC
    Réponses: 12
    Dernier message: 19/03/2004, 16h28
  2. [math] somme de plusieurs vecteurs à 3 dimensions
    Par teska dans le forum Mathématiques
    Réponses: 5
    Dernier message: 04/06/2003, 21h40
  3. Récuperer les coordonnées d'un vecteur
    Par kerzut dans le forum OpenGL
    Réponses: 5
    Dernier message: 15/04/2003, 11h51
  4. Zoom sur des vecteurs ou lignes
    Par mat.M dans le forum Algorithmes et structures de données
    Réponses: 7
    Dernier message: 25/11/2002, 10h40
  5. matrices * vecteur
    Par delire8 dans le forum Algorithmes et structures de données
    Réponses: 15
    Dernier message: 07/09/2002, 14h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo