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 :

vector et find, find_if


Sujet :

SL & STL C++

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 23
    Points : 27
    Points
    27
    Par défaut vector et find, find_if
    Bonjour,

    Voilà mon soucis:

    J'ai un vector V contenant des vector de 3 float.

    Par exemple V contient une liste de personnes et chaque élément de V est un vector avec en premier élément l'age, en second la taille et en troisième le poids.

    Je souhaiterais faire une fonction qui me permette de trouver une personne en fonction de critères sur son poids, sa taille ou son age par exemple je voudrais trouver une personne de plus de 25 ans avec un poids entre 80 et 100 kilos et un age inférieur à 50 ans.

    J'ai commencé par essayer un algorithme à la main sans succès. Je me tourne donc vers les fonctions find et surtout find_if.

    Malgré avoir lu de nombreuses explications (notamment SGI) je n'ai pas trouvé d'exemples d'application de find_if dont je pourrais m'inspirer.

    Merci pour votre aide.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Salut,

    Ta fonction find_if va ressembler à cela

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find_if(V.begin(),V.end(),P);
    où V est ton vecteur, P est un prédicat, que tu vas initialiser en lui passant les paramètres de ta requête. Si ta requête est toujours la même (ou si tu utilises un tout petit nombre de requêtes), tu peux écrire ce prédicat commeune fonction renvoyant un booléen.

    Quelque chose comme (ton_type est le type des enregistrements de ton vecteur V)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    bool P(ton_type &t)
    {
    return (t.age>=18 && t.age<50 && t.poids>=80 && t.poids<100);
    }
    Pour rendre cela plus paramétrable, il faut définir une classe fonction, quelque chose comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct requete : public unary_function<ton_type, bool>
        {
          double min_age,max_age,min_poids,max_poids;
     
          bool operator()(ton_type p) { return (t.age>=min_age && t.age<max_age && t.poids>=min_poids && t.poids<max_poids; }
        };
    les paramètres de ta requete sont alors les membres de la classe, et tu les initialises via des fonctions, ou un constructeur... et tu passes à find_if() une instance de cette classe, initialisée avec les paramètres de la requête...

    Francois

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 23
    Points : 27
    Points
    27
    Par défaut
    Alors,

    J'ai essayé de faire ce que tu m'as dit à savoir l'utilisation d'une classe fonction. Mais c'est là que je commence à caler. Je comprend pas le sens des termes qui interviennent dans la création de cette fonction. operator() c'est quoi? le nom de l'opérateur booléen?
    Quand j'appelle ma fonction find_if, quel va être le 3ème paramètre? requete() avec quels paramètres?

    Merci de ta réponse.

  4. #4
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par thhomas Voir le message
    Alors,

    J'ai essayé de faire ce que tu m'as dit à savoir l'utilisation d'une classe fonction. Mais c'est là que je commence à caler. Je comprend pas le sens des termes qui interviennent dans la création de cette fonction. operator() c'est quoi? le nom de l'opérateur booléen?
    Quand j'appelle ma fonction find_if, quel va être le 3ème paramètre? requete() avec quels paramètres?

    Merci de ta réponse.
    operator(), c'est l'opérateur (). C'est à dire une fonction qui prend en paramètre quelquechose. Une classe avec un opérateur ainsi défini s'appelle une foncteur. C'est à peu près équivalent à une fonction.
    D'ailleurs, les deux exemples de code de fcharton sont équivalent. L'un utilise une fonction, l'autre un foncteur.

    Le troisième paramètre de find_if, c'est un prédicat. Celà peut être une fonction ou un foncteur qui renvoie un booléen.

    Quand tu écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::find_if(vect.begin(), vect.end(), P)
    C'est grosso modo équivalent à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    for (int i = 0; i < vect.end(); i++)
    {
       bool res = P(vect[i]);
       if (res == true)
       {
           // on renvoie un itérateur (pointeur) sur la position actuelle
       }
    }

  5. #5
    Invité
    Invité(e)
    Par défaut
    operator() c'est une surcharge d'opérateur. En C++, on peut redéfinir le sens des opérateurs. Par exemple, si tu redéfinis l'addition pour une classe MaClasse, tu peux écrire

    c=a+b;

    où a, b et c sont des instance de MaClasse.

    Ici, l'opérateur qu'on surcharge c'est "()", tu sais, le truc qu'on tape quand on appelle une fonction... Donc, ce code va s'exécuter si je définis une instance de requete :

    quand je fais

    où v est un ton_type, et cela renvoie un booléen (cf la définition de la classe comme unary_function<ton_type, bool>).

    En gros, un objet fonction, c'est une classe qui sait "s'exécuter" quand on fait

    Mais comme ca peut contenir des données et des fonctions membres, c'est bien plus général qu'une fonction normale. Si tu t'en sens le courage, tu peux définir tout un vocabulaire SQL dans cette classe requete.

    Pour l'utiliser dans find_if, tu vas devoir faire quelque chose comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    requete r;
    r.min_age=18;
    r.max_age=50;
    r.min_poids=80:
    r.max_poids=100;
    find_if(v.begin(),v.end(),r);
    Tu ne passes que l'instance (r) à find_if, il se charge du reste...

    Mais bon, si tu veux faire ca bien, il te faut un manuel STL et un peu d'entrainement... C'est pas très dur les objets fonction, mais ca vient avec la pratique.

    Francois

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 23
    Points : 27
    Points
    27
    Par défaut
    Tout d'abord merci beaucoup pour toutes ces explications.
    Je commence à comprendre un peu à quoi tout cela rime. Et j'ai du coup redéfinit exactement mon besoin.
    J'ai réussi à construire la structure et le booléen mais quand je l'envoie dans le find_if il me met toujours une erreur. Je vous la renvoie sachant que je compile avec DEV-C++

    56 \validation.c no matching function for call to `find_if(__gnu_cxx::__normal_iterator<float*, std::vector<float, std::allocator<float> > >, __gnu_cxx::__normal_iterator<float*, std::vector<float, std::allocator<float> > >, validation_QoS(std::vector<std::vector<float, std::allocator<float> >, std::allocator<std::vector<float, std::allocator<float> > > >&, std::vector<std::vector<float, std::allocator<float> >, std::allocator<std::vector<float, std::allocator<float> > > >&)::requete&)'
    Mais je ne pense pas qu'elle sera très utile.

    Par ailleurs, je ne souhaite plus trouver l'élément dont la taille se situe dans un intervalle pour un age donné mais je cherche l'élément dont la taille est maximale pour une catégorie d'age. Il va falloir faire appel à des notions de maximums et je ne sais pas si il y a des algorithmes déjà présents dans la STL.

    Thomas.

  7. #7
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    On pourrait avoir le code qui va bien avec?
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 23
    Points : 27
    Points
    27
    Par défaut
    Merci à tous pour vos explications.
    J'ai finalement utilisé l'algorithme max_element pour faire ma sélection d'élément.

Discussions similaires

  1. fonction find et vector ? [c++]
    Par panthere noire dans le forum Débuter
    Réponses: 6
    Dernier message: 29/07/2010, 10h27
  2. Vector et find() ?
    Par laurentm44 dans le forum C++
    Réponses: 12
    Dernier message: 18/06/2010, 14h01
  3. find avec un vector de pair
    Par Pg043 dans le forum SL & STL
    Réponses: 12
    Dernier message: 05/11/2009, 17h18
  4. find sur un vector qui contient une structure
    Par kunda dans le forum SL & STL
    Réponses: 14
    Dernier message: 28/04/2009, 21h35
  5. find sur le vector
    Par LeXo dans le forum SL & STL
    Réponses: 17
    Dernier message: 12/02/2008, 14h18

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