je suis en train d'apprendre les conteneurs de la stl, et dans quel cas
utiliser l'un plutôt que l'autre... j'ai un petit problème a vous
soumettre.
Disons que j'ai un objet A qui contient un string et un ensemble
ordonné de pointeurs sur des objets A.
pour cet ensemble ordonné, j'utilise std::set, qui me permet d'ajouter
des éléments qui sont inséré directement au bon endroit selon la
relation d'ordre définie pour A.
maintenant j'ai quelques problèmes :
class MaString
{
public:
string s;
set<const MaString *> tab;
le vector<MaString> pris en argument par MiseAjour contient tout un tas
d'objet MaString non ordonnés, dont l'objet en cours lui même, et le
set de l'objet, doit se remplir avec les pointeurs vers les autres
objets du vector, sauf bien sûr le pointeur sur lui même. Et les
pointeurs doivent etre rangés selon la relation d'ordre de MaString.
(la relation d'ordre de MaString est tout simplement l'opérateur '<' de
son membre string)
je n'ai pas l'impression que ça marche correctement, de plus, la
méthode 'insert' doit renvoyer un objet 'pair<iterator,bool>' indiquant
si l'insertion a bien eu lieu, si j'ai bien compris. Mais je pige pas
trop ce qu'est cet objet, ni comment le déclarer pour vérifier le
retour de insert.
maintenant autre question, les set ne disposent pas de l'opérateur []
pour accéder a un de leurs membres, ou alors j'ai pas vu pas
compris...? donc le moyen pour aller sur un objet d'un set et
l'iterateur... je m'en sert pour ma surcharge d'affichage de mon objet
MaString, mais apparement j'ai une faute sur l'iterator, et je
comprends pas
En mettant s3.AjouterCluster(Cluster(1,2,10)); s3.AjouterCluster(Cluster(-4,5,8)); s3.AjouterCluster(Cluster(0,0,0)); dans ton 'main', le programme m?affiche [...] cluster 2 : ======================================= > Position : [ 0, 0, 0 ] barycentre : [ 0, 0, 0 ] Generation : 1 Mes fils : ---------- Mes influences : ---------------- -Position : [ 1, 2, 10 ] D = 10.25 ======================================== > (absence de "-Position : [ -4, 5, 8 ] D = 10.25" ; je ne sais pas si c?est important ou pas pour ce que tu veux faire - sinon voir 'std::multiset')
en effet pour le moment j'ai fait exprès d'avoir ça. je fais petit à petit, une difficulté à la fois.
Le problème vient du fait que 'std::vector' a besoin du constructeur de copie et de l?opérateur d?affectation, et ta classe 'Cluster' utilise les opérations générées par le compilateur qui ne marchent pas bien parce que le champ ?Influences? aura un functeur de comparaison pointant sur le 'Cluster' d?origine plutôt que l?objet courant. Par conséquent, les distances à l?insertion sont calculées par rapport à ce premier... En mettant
Cluster& Cluster::operator=(Cluster const& c) { Position = c.Position; Influences.clear(); Influences.insert(c.Influences.begin(), c.Influences.end()); Parent = c.Parent; Generation = c.Generation; return *this; }
cela se passe mieux.
ah je me suis douté hier que l'erreur devait venir du vector et de ce 'this'... mais j'ai un peu de mal à vraiment comprendre l'affaire.. car dans http://nicolas.aunai.free.fr/particule/points/ok j'utilise aussi un vector et pourtant apparement ça marche très bien donc je vois pas pk.
Reste la question si la classe 'Cluster' doit réellement avoir une sémantique de valeur ou s?il faut en interdire les opérations de copie (ce qui obligerait entre autres de remplacer 'std::vector<Cluster>' par 'std::vector<Cluster*>').
En mettant
s3.AjouterCluster(Cluster(1,2,10));
s3.AjouterCluster(Cluster(-4,5,8));
s3.AjouterCluster(Cluster(0,0,0));
dans ton 'main', le programme m?affiche
[...]
cluster 2 : ======================================= > Position : [ 0, 0, 0 ] barycentre : [ 0, 0, 0 ] Generation : 1
Mes fils : ---------- Mes influences : ---------------- -Position : [ 1, 2,
10 ] D = 10.25
======================================== >
(absence de "-Position : [ -4, 5, 8 ] D = 10.25" ; je ne sais pas si c?est
important ou pas pour ce que tu veux faire - sinon voir 'std::multiset')
en effet pour le moment j'ai fait exprès d'avoir ça. je fais petit à
petit, une difficulté à la fois.
Le problème vient du fait que 'std::vector' a besoin du constructeur de
copie et de l?opérateur d?affectation, et ta classe 'Cluster' utilise
les opérations générées par le compilateur qui ne marchent pas bien parce
que le champ ?Influences? aura un functeur de comparaison pointant sur
le 'Cluster' d?origine plutôt que l?objet courant. Par conséquent,
les distances à l?insertion sont calculées par rapport à ce premier...
En mettant
Cluster& Cluster::operator=(Cluster const& c)
{
Position = c.Position;
Influences.clear();
Influences.insert(c.Influences.begin(), c.Influences.end());
Parent = c.Parent;
Generation = c.Generation;
return *this;
}
cela se passe mieux.
ah je me suis douté hier que l'erreur devait venir du vector et de ce
'this'... mais j'ai un peu de mal à vraiment comprendre l'affaire.. car
dans http://nicolas.aunai.free.fr/particule/points/ok j'utilise aussi
un vector et pourtant apparement ça marche très bien donc je vois pas
pk.
Reste la question si la classe 'Cluster' doit réellement avoir une sémantique
de valeur ou s?il faut en interdire les opérations de copie (ce qui
obligerait
entre autres de remplacer 'std::vector<Cluster>' par
'std::vector<Cluster*>').
En mettant s3.AjouterCluster(Cluster(1,2,10)); s3.AjouterCluster(Cluster(-4,5,8)); s3.AjouterCluster(Cluster(0,0,0)); dans ton 'main', le programme m?affiche [...] cluster 2 : ======================================= > Position : [ 0, 0, 0 ] barycentre : [ 0, 0, 0 ] Generation : 1 Mes fils : ---------- Mes influences : ---------------- -Position : [ 1, 2, 10 ] D = 10.25 ======================================== > (absence de "-Position : [ -4, 5, 8 ] D = 10.25" ; je ne sais pas si c?est important ou pas pour ce que tu veux faire - sinon voir 'std::multiset')
en effet pour le moment j'ai fait exprès d'avoir ça. je fais petit à petit, une difficulté à la fois.
Le problème vient du fait que 'std::vector' a besoin du constructeur de copie et de l?opérateur d?affectation, et ta classe 'Cluster' utilise les opérations générées par le compilateur qui ne marchent pas bien parce que le champ ?Influences? aura un functeur de comparaison pointant sur le 'Cluster' d?origine plutôt que l?objet courant. Par conséquent, les distances à l?insertion sont calculées par rapport à ce premier... En mettant
Cluster& Cluster::operator=(Cluster const& c) { Position = c.Position; Influences.clear(); Influences.insert(c.Influences.begin(), c.Influences.end()); Parent = c.Parent; Generation = c.Generation; return *this; }
cela se passe mieux.
ah je me suis douté hier que l'erreur devait venir du vector et de ce 'this'... mais j'ai un peu de mal à vraiment comprendre l'affaire.. car dans http://nicolas.aunai.free.fr/particule/points/ok j'utilise aussi un vector et pourtant apparement ça marche très bien donc je vois pas pk.
Reste la question si la classe 'Cluster' doit réellement avoir une sémantique de valeur ou s?il faut en interdire les opérations de copie (ce qui obligerait entre autres de remplacer 'std::vector<Cluster>' par 'std::vector<Cluster*>').
Une autre solution, qui évite le constructeur de copie et l'opérateur d'affectation est de modifier CompareDistance pour ne garder que l'information utile :
class CompareDistance { private: // const Cluster *p; V3D position_;
c'est vrai mais plus tard, la position changera aussi beaucoup au cours du temps alors je sais pas si ça pourra poser des problèmes... et j'aime pas trop l'idée de répéter un champ comme ça :)
Le main() de Nicolas est en O(n^2 ln n) ou n est la taille d'un std::vector<Cluster>. N'est-ce pas un début de réponse ?
hum, un peu HS mais comment tu fais pour calculer ce 0(n^2ln(n)) ? c'est pas super super comme complexité ça....
Une autre solution, qui évite le constructeur de copie et l'opérateur
d'affectation est de modifier CompareDistance pour ne garder que
l'information utile :
class CompareDistance
{
private:
// const Cluster *p;
V3D position_;
c'est vrai mais plus tard, la position changera aussi beaucoup au cours
du temps alors je sais pas si ça pourra poser des problèmes... et
j'aime pas trop l'idée de répéter un champ comme ça :)
Le main() de Nicolas est en O(n^2 ln n) ou n est la taille d'un
std::vector<Cluster>. N'est-ce pas un début de réponse ?
hum, un peu HS mais comment tu fais pour calculer ce 0(n^2ln(n)) ?
c'est pas super super comme complexité ça....
Une autre solution, qui évite le constructeur de copie et l'opérateur d'affectation est de modifier CompareDistance pour ne garder que l'information utile :
class CompareDistance { private: // const Cluster *p; V3D position_;
c'est vrai mais plus tard, la position changera aussi beaucoup au cours du temps alors je sais pas si ça pourra poser des problèmes... et j'aime pas trop l'idée de répéter un champ comme ça :)
Le main() de Nicolas est en O(n^2 ln n) ou n est la taille d'un std::vector<Cluster>. N'est-ce pas un début de réponse ?
hum, un peu HS mais comment tu fais pour calculer ce 0(n^2ln(n)) ? c'est pas super super comme complexité ça....
Le main() de Nicolas est en O(n^2 ln n) ou n est la taille d'un std::vector<Cluster>. N'est-ce pas un début de réponse ?
hum, un peu HS mais comment tu fais pour calculer ce 0(n^2ln(n)) ? c'est pas super super comme complexité ça....
main: Pour chaque cluster -- n fois Construire une suite ordonnée des n-1 clusters
Construire une suite ordonnée des n-1 clusters: Insérerer un cluster dans un suite de longueur p -- ln p ln 1 + ln 2 + ln 3 + ... + ln n est équivalent à n ln n -- Franck Branjonneau
Nicolas Aunai <nicolas.aunai@free.fr> écrivait:
Franck Branjonneau a exposé le 25/02/2004 :
Le main() de Nicolas est en O(n^2 ln n) ou n est la taille d'un
std::vector<Cluster>. N'est-ce pas un début de réponse ?
hum, un peu HS mais comment tu fais pour calculer ce 0(n^2ln(n)) ?
c'est pas super super comme complexité ça....
main:
Pour chaque cluster -- n fois
Construire une suite ordonnée des n-1 clusters
Construire une suite ordonnée des n-1 clusters:
Insérerer un cluster dans un suite de longueur p -- ln p
ln 1 + ln 2 + ln 3 + ... + ln n est équivalent à n ln n
--
Franck Branjonneau <fasbjx@free.fr>
Le main() de Nicolas est en O(n^2 ln n) ou n est la taille d'un std::vector<Cluster>. N'est-ce pas un début de réponse ?
hum, un peu HS mais comment tu fais pour calculer ce 0(n^2ln(n)) ? c'est pas super super comme complexité ça....
main: Pour chaque cluster -- n fois Construire une suite ordonnée des n-1 clusters
Construire une suite ordonnée des n-1 clusters: Insérerer un cluster dans un suite de longueur p -- ln p ln 1 + ln 2 + ln 3 + ... + ln n est équivalent à n ln n -- Franck Branjonneau