vector/list de structures, recherche d'elements de la structure [STL] - C++ - Programmation
Marsh Posté le 13-01-2003 à 16:55:23
Une suggestion : remplacer la structure par une classe (c++)
Code :
|
Sinon, pour l'algo de recherche :
exemple:
Code :
|
A réfléchir
kason
Marsh Posté le 13-01-2003 à 17:07:25
merci de ta réponse
je me demandais plutot si c'était possible en fait d'utiliser l'algo
iterator find(key_type clef)
tjrs avec ces hisoires d'itérateur (que je conceptualise pas tjrs tres bien, même si ton exempel m'éclaire tres bien , en + c génial de pouvoir incrémenter les itérateurs, qui s'incrément comme il faut ), plutot que mon (ton) pseudo algo de recherche,
et sans définir de classe
(par exemple, en passsant une sorte d'argument spécial a la fonction recherche, un itérateur subliminial, que sais-je....
Marsh Posté le 13-01-2003 à 18:42:57
le code de std::find est trivial, mais puisqu'il existe déjà autant pas le retaper
petites corrections
Code :
|
quant à ta question, à toi de définir operator== et operator< par la meme occasion (et tous les autres)
apres
Code :
|
sinon, si tu veux rechercher un élément obéissant à une certaine regle, le mieux c'est de faire
Code :
|
ça devrait marcher
Marsh Posté le 13-01-2003 à 18:54:27
au fait: tes methodes "accessor" qui ne modifient pas l'objet doivent etre déclarer const
void MaClasse::fonction() const;
Marsh Posté le 13-01-2003 à 18:54:34
un iterateur c'est une abstraction de pointeur (pour resumer)
ou plutot un pointeur c'est une implementation particuliere
d'un iterateur aleatoire.
Il y a quatre types d'iterateurs:
name ou reference: qui te permet de lire la valeur avec *
forward iterateur: qui te permet de lire la valeur avec *
et d'avancer dans ta structure avec ++.
bidirectional iterator: qui te permet de lire la valeur
avec * et d'avancer avec ++ et reculer dans ta structure avec --.
random iterator: qui te permet de lire la valeur avec * et d'avancer et reculer dans ta structure avec ++, -- ainsi que + n et - n.
Il manque une abstraction supplementaire qui permettrait d'avancer dans une structure en profondeur et en largeur mais peut-etre que ca existe je n'en sais pas plus .
find te renvoie l'iterateur qui pointe sur la premiere occurrence de l'element que tu as passe en parametre. Evidemment il est sous-optimal pour un vector trie..
Ce que tu cherches a faire toi c'est plutot un map
donc autant utiliser la map existante:
map<string, int>
permet d'associer l'entier n a une chaine de caractere.
Si tu as une version adaptee de la STL (non standard)
tu peux utiliser une hash_map egalement.
LeGreg
Marsh Posté le 13-01-2003 à 18:54:54
Je prefere comme ça :
Code :
|
Mais faut connaitre l'utilisation de bind2nd et bind1st
Edit : petite erreur d'ecriture
Marsh Posté le 13-01-2003 à 18:55:22
merci (de ta réponse )de vous réponses , mais je suis un peu dépassé la
l'idée qui est la mienne serait plus proche d'une mini base de données
alors la je fais une classe MaFiche avec mes différents champs et méthodes, mais ensuite, mon esprit s'embrouille....
Marsh Posté le 13-01-2003 à 18:58:38
si je comprend bien le find_if permet de passer l'argumetn regle pour la recherche ???
Marsh Posté le 13-01-2003 à 18:59:09
Kristoph a écrit : Je prefere comme ça :
|
find_if
mais l'ecriture est aussi courte ave cmon exemple
VectorOfLog::iterator result=std::find(MyVector.begin(), MyVector.end(), VectorOfLogFinder("xxxx" ))
le problème des bind, c'est que ça ne fonctionne que pour les fonctions binaires. si la recherche doit s'effectuer sur plus d'un critere, on est obligé de passer par un objet fonction comme j'ai montré
Marsh Posté le 13-01-2003 à 18:59:53
farib a écrit : si je comprend bien le find_if permet de passer l'argumetn regle pour la recherche ??? |
oui, cet argument est un prédicat qui renvoie vrai si l'élément courant correspond au critere de recherche
Marsh Posté le 13-01-2003 à 19:02:11
Code :
|
les deux pts c pour quoi faire déja
(dsl, je repose ma question)
Marsh Posté le 13-01-2003 à 19:03:56
c'est pour construire les membres. sinon, ils sont construit avec leur constructeur par défaut, puis affecter dans le corps du constructeur, ce qui est bien plus couteux
edit: a pas peur
http://www.sgi.com/tech/stl/
Marsh Posté le 13-01-2003 à 19:04:12
Citation : VectorOfLog::iterator result=std::find(MyVector.begin(), MyVector.end(), bind2nd(EqualUser(),"xxx" )); |
tu voulais dire find_if non ?
LeGreg
Marsh Posté le 13-01-2003 à 19:05:05
legreg a écrit :
|
toi t'es ultra grillaid
Marsh Posté le 13-01-2003 à 19:08:11
++Taz a écrit : c'est pour construire les membres. sinon, ils sont construit avec leur constructeur par défaut, puis affecter dans le corps du constructeur, ce qui est bien plus couteux |
chuis content, g fais venir tous les gros boss de c++
donc pour effectuer une recherche, il convient de définir le critere de recherche, et également la regle de comparaison (operator =) mais pourquoi l'opérateur () ?
Marsh Posté le 13-01-2003 à 19:10:32
operator== c'est la comparaison et pas =
oui, il convient
voire les objets fonctions. le test est alors réalisé comme ça
trucfinder("xxx" )
if(trucfinder(MyVector[0]))
qui n'est pas un constructeur mais operator()
Marsh Posté le 13-01-2003 à 19:20:04
Code :
|
les deux pts c pour quoi faire déja
(dsl, je repose ma question)
Marsh Posté le 13-01-2003 à 19:24:47
++Taz a écrit : c'est pour construire les membres. sinon, ils sont construit avec leur constructeur par défaut, puis affecter dans le corps du constructeur, ce qui est bien plus couteux |
Marsh Posté le 13-01-2003 à 20:24:48
enfin bon, la construction par défaut, la c juste une déclaration de int et string....
Marsh Posté le 13-01-2003 à 21:57:11
pour un int, peut etre pas, pour une string un peu moins: mais prenons un exemple.
on a un objet avec un constructeur par défaut, un constructeur par recopie et un opérateur d'affectation
- ta méthode:
1) le constructeur par défaut alloue des ressources pour construire l'objet. ce n'est pas parce qu'il sagit d'un contructeur par défaut que l'objet construit est vide, loin de là.
2) l'affectation: l'opérateur d'affectation doit nettoyer les ressources acquises par l'objet, puis en réallouer, et recopier (ou une autre opération selon) les données.
- ma méthode:
1) le constructeur par recopie alloue les ressources nécessaires et effectue la copie de donnée
prends des bonnes habitudes.
d'autant plus qu'appeler les constructeurs est souvent indispensables.
taiste:
Code :
|
implémentes moi ces 2 constructeurs: le par défaut donne à vecteur une taille de 100 éléments. le second, lui donne une taille de size éléments initialisés à init.
enjoy!
Marsh Posté le 13-01-2003 à 23:07:31
et par défaut c de combien la taille d'un vector a sa création ?
Marsh Posté le 14-01-2003 à 07:10:25
farib a écrit : et par défaut c de combien la taille d'un vector a sa création ? |
0, mais la je veux qu'à la sortie du constructeur il fasse soit 100 soit size
Marsh Posté le 14-01-2003 à 08:01:54
derniere série de question avant de mettre en application, si je veux utiliser les fonctions de tri de la STL sur ma structure/classe, ca marche un peu sur le même principe, il faut que je définisse mes critères de comparaison ?
Marsh Posté le 14-01-2003 à 10:35:09
La valeur par defaut des fonctions de tri utilise l'opérateur < s'il est défini. Mais tu peux toujours passer en paramètre une fonction de comparaison custom.
Attention, tu dois passer une comparaison stricte "<" et non pas du type "<=".
Marsh Posté le 14-01-2003 à 14:29:38
j'ai un pb avec find_if
Code :
|
Si vous désirez effectuer une recherche sur un autre critère que l'égalité de valeur, vous devrez utiliser l'algorithme find_if. Celui-ci prend un prédicat en paramètre à la place de la valeur. C'est la valeur de ce prédicat, appliqué à l'élément courant dans le parcours des éléments de la séquence définie par les itérateurs premier et dernier, qui permettra de déterminer si cet élément est celui recherché ou non. La valeur retournée est l'itérateur dernier si aucun élément ne correspond au critère de recherche. La complexité de cet algorithme est linéaire en fonction du nombre d'éléments de la séquence d'éléments dans laquelle la recherche se fait.
supair, et si le l'element trouvé est en derniere position on fait comment pour savoir s'il est trouvé ou si c'est la fin (g pas tt compris la )
a moisn que "dernier" soit plsu un délimiteur que le dernier élément de mon vector (dans mon cas)
Marsh Posté le 14-01-2003 à 14:33:20
C'est comme en C. Le premier est inclus et le dernier est exclus. En gros, v.end() correspond à un iterateur qui pointe juste après la fin du tableau. Mais v.begin() pointe vraiment sur le premier element du tableau.
Marsh Posté le 14-01-2003 à 14:48:38
Code :
|
Code :
|
++Taz ! t mauvais je comprend petit a petit, masi surement
blague a part, pkoi des passages par référence ?
Marsh Posté le 14-01-2003 à 15:20:54
arf, je dé-conste dans
Code :
|
et ca compile
Marsh Posté le 14-01-2003 à 15:21:22
++Taz a écrit : au fait: tes methodes "accessor" qui ne modifient pas l'objet doivent etre déclarer const |
si tu lisais tu n'aurais pas autant de problème. find_if travaille sur des objets constants, donc pas question d'executées de fonctions membre non-const, dou le problème avec Log::GetUse
r()
si tu y arrives pas j'ai ton exemple qui compile, demandes et je te maile
passé une const &, ça évite de passer une copie
Marsh Posté le 14-01-2003 à 15:33:20
bah je retire le const dans ta déclaration de l'opérateur (), ca compile....
Marsh Posté le 14-01-2003 à 15:36:00
réparé, en effet, merci
pkoi utiliser encore en c++ des passages par non référence alors ?
Marsh Posté le 14-01-2003 à 15:49:02
ReplyMarsh Posté le 14-01-2003 à 16:09:19
Code :
|
c c'est un pointeur de fonctrion ?
je fais
Code :
|
ca marche
je commence a capter
par contre, y'a t-il un moyen de faire la même chose, en surchargeant l'opérateur < ?
Marsh Posté le 14-01-2003 à 16:42:55
farib a écrit : bah je retire le const dans ta déclaration de l'opérateur (), ca compile.... |
pas la. il faut que tu en rajoutes un à tes fonctions observatrices de Log (genre getuser, etc)
edit: le "ça compile", evite ce genre de truc, sinon la prochaine fois que t'as un problème, je te donnerai seulement un truc qui "compile"
Marsh Posté le 14-01-2003 à 16:45:23
farib a écrit : tout baigne, Da C++ P0w3r R0x0r |
va pas trop vite padawan
Compare c c'est pas un pointeur de fonction, c'est un argmuent de type de template. donc ca peut marcher avec une fonction mais surtout avec un un objet-fonction (functor, c'est à dire un objet qui implémentes l'operator())
Marsh Posté le 14-01-2003 à 16:51:09
++Taz a écrit : va pas trop vite padawan |
donc en surchargeant l'opérateur <
Marsh Posté le 14-01-2003 à 16:51:38
Faites un tour du cote de mem_fun ptr_fun et autres choses de ce genre dans la STL. C'set utilisé pour convertir des fonction "normales" en fonctions utilisables dans certaines parties plus exigentes de la STL.
Marsh Posté le 14-01-2003 à 16:54:52
Kristoph a écrit : Faites un tour du cote de mem_fun ptr_fun et autres choses de ce genre dans la STL. C'set utilisé pour convertir des fonction "normales" en fonctions utilisables dans certaines parties plus exigentes de la STL. |
vas pas l'embrouiller
Marsh Posté le 14-01-2003 à 16:56:22
farib a écrit : |
à ce moment la plus besoin de predicat. donc soit tu crées un prédicat, soit tu surcharge operator<.
si tu veux en discuter, contacte moi sur ICQ.
edit: je crois qu'avant de t'avancer dans STL tu devrais maitriser les templates et toutes les bases du langage, ça te rendra moins con (pas plus intelligent )et apres tu comprendras le fonctionnement de STL et son implémentation rapidement
Marsh Posté le 13-01-2003 à 12:14:58
voila je veux faire un ptit prog en c++ pour manipuler des logs
pour simplifier, mes interrogations sont les suivantes
je pense que c'est possibles, avec les iterators ou autres, mais la stl est un peu complexe et si je sais utiliser un vecteur simple, les operations plus puissantes sont un peu compliquees
j'ai essaye de lire le cours de christian casteyde, mais c un peu chaud quand meme
je voulais savoir comment rechercher directement si possible dans le vecteur, avec les fonctions de la stl, par exemple le n de la structure qui contient un User si je passe en argument un string (pour incrementer son score par exemple), quitte ensuite a utiliser des fonctions d'insertion, de tri ( ordre alphabetique, ou classement, etc...)
c'est pas les iterateurs ou un truc dans le genre qui permettent de faire ca ?
bref, ++Taz, et autres integristes du char * bienvenus ;-)
Message édité par farib le 13-01-2003 à 12:40:53