Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1535 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  (STL) algo copy_if

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

(STL) algo copy_if

n°772138
xterminhat​e
Si vis pacem, para bellum.
Posté le 21-06-2004 à 23:07:46  profilanswer
 

Pouvez vous m'aider à completer ce fragment de code.

Code :
  1. bool p( const T& );
  2. list<T> l1;
  3. list<T> l2;
  4. // construire l2 à partir des éléments de l1 si le prédicat p est vrai
  5. ....( l1.begin(), l1.end(), .... );


 
Il me semble que cela est possible en une seule instruction mais je ne me rappelle plus comment faire.


Message édité par xterminhate le 11-08-2004 à 01:33:33

---------------
Cordialement, Xterm-in'Hate...
mood
Publicité
Posté le 21-06-2004 à 23:07:46  profilanswer
 

n°772144
Taz
bisounours-codeur
Posté le 21-06-2004 à 23:12:27  profilanswer
 

avec un algo genre remove_copy_if + un back_inserter


Message édité par Taz le 21-06-2004 à 23:26:11
n°772145
xterminhat​e
Si vis pacem, para bellum.
Posté le 21-06-2004 à 23:13:53  profilanswer
 

Et bien c'est ce à quoi j'ai pensé en premier et en relisant le manuel de transform, je n'ai pas trouvé la bonne méthode :/


---------------
Cordialement, Xterm-in'Hate...
n°772148
xterminhat​e
Si vis pacem, para bellum.
Posté le 21-06-2004 à 23:16:42  profilanswer
 

Comment associer un predicat à tranform/back_inserter ?


Message édité par xterminhate le 21-06-2004 à 23:16:53

---------------
Cordialement, Xterm-in'Hate...
n°772156
Taz
bisounours-codeur
Posté le 21-06-2004 à 23:26:26  profilanswer
 

wait l'exemple arrive

n°772171
Taz
bisounours-codeur
Posté le 21-06-2004 à 23:37:17  profilanswer
 

Code :
  1. #include <list>
  2. #include <algorithm>
  3. #include <iterator>
  4. #include <iostream>
  5. #include <functional>
  6. namespace
  7. {
  8.   template<typename InputIterator,
  9.    typename OutputIterator,
  10.    typename Predicate>
  11.   inline void copy_if(InputIterator first, InputIterator last,
  12.        OutputIterator out,
  13.        Predicate p)
  14.   {
  15.     while(first != last)
  16.       {
  17. if( p(*first) )
  18.   {
  19.     *out++ = *first;
  20.   }
  21. ++first;
  22.       }
  23.   }
  24.   template<typename T>
  25.   inline bool selector(const T &t)
  26.   {
  27.     return t & 1;
  28.   }
  29. }
  30. int main()
  31. {
  32.   int integers[] = {1, 2, 3, 4, 5, 6};
  33.   // j'utilise la liste pour te faire plaisir, sinon y en a pas besoin
  34.   // autant tout sortir sur std::cout
  35.   typedef std::list<int> Liste;
  36.   Liste res;
  37.   std::remove_copy_if(&integers[0],
  38.   &integers[0] + sizeof integers / sizeof integers[0],
  39.   std::back_inserter(res),
  40.   selector<Liste::value_type> );
  41.   std::copy(res.begin(), res.end(),
  42.     std::ostream_iterator< Liste::value_type >(std::cout, ", " ));
  43.   std::cout << std::endl;
  44.   res.clear();
  45.   copy_if(&integers[0],
  46.   &integers[0] + sizeof integers / sizeof integers[0],
  47.   std::back_inserter(res),
  48.   selector<Liste::value_type> );
  49.   std::copy(res.begin(), res.end(),
  50.     std::ostream_iterator< Liste::value_type >(std::cout, ", " ));
  51.   std::cout << std::endl;
  52. }


 
bon j'ai pas poussé plus loin l'exemple full stl, il aurait fallut faire la négation. tu vois bien qu'avec un petit algo simple fait maison, on y arrive. la STL n'est pas complète loin de là : il aurait fallut passer par boost pour faire ça un peu plus proprement. y en a marre de pas avoir de begin(tab) et de end(tab) de devoir se taper l'écriture C ...

n°772175
Taz
bisounours-codeur
Posté le 21-06-2004 à 23:38:21  profilanswer
 

c'est aussi facile de ne bricoler un petit FilteringOutputIterator auquel cas, un simple std::copy fonctionnera super bien

n°772189
xterminhat​e
Si vis pacem, para bellum.
Posté le 21-06-2004 à 23:45:22  profilanswer
 

Bien, la STL manque vraiment d'un copy_if comme tu l'as décrit.
 
On trouve la définition de FilteringOutputIterator sur SGI ?


---------------
Cordialement, Xterm-in'Hate...
n°772200
xterminhat​e
Si vis pacem, para bellum.
Posté le 21-06-2004 à 23:51:04  profilanswer
 

Merci pour l'exemple, je range ton copy_if dans ma boite à outils à coté de la STL ;)


---------------
Cordialement, Xterm-in'Hate...
n°772202
Taz
bisounours-codeur
Posté le 21-06-2004 à 23:52:35  profilanswer
 

nulle part un FilteringOuputIterator, c'est juste un OutputIterator qui filtre ce qu'on lui demande de sortir

mood
Publicité
Posté le 21-06-2004 à 23:52:35  profilanswer
 

n°772217
Taz
bisounours-codeur
Posté le 22-06-2004 à 00:11:48  profilanswer
 

Code :
  1. #include <list>
  2. #include <algorithm>
  3. #include <iterator>
  4. #include <iostream>
  5. namespace
  6. {
  7.   template<typename T>
  8.   inline bool selector(const T &t)
  9.   {
  10.     return t & 1;
  11.   }
  12.   template<typename T,
  13.    typename OutputIterator,
  14.    typename Predicate>
  15.   struct FilteringOutputIterator
  16.   {
  17.     OutputIterator out;
  18.     Predicate pred;
  19.     FilteringOutputIterator(OutputIterator o, Predicate p)
  20.       : out(o), pred(p)
  21.     { }
  22.     FilteringOutputIterator&
  23.     operator=(const T &t)
  24.     {
  25.       if( pred(t) ) *out++ = t;
  26.       return *this;
  27.     }
  28.     FilteringOutputIterator&
  29.     operator*() { return *this; }
  30.     FilteringOutputIterator&
  31.     operator++() { return *this; }
  32.     FilteringOutputIterator&
  33.     operator++(int) { return *this; }
  34.   };
  35.    template<typename T,
  36.    typename OutputIterator,
  37.    typename Predicate>
  38.    inline FilteringOutputIterator<T, OutputIterator, Predicate>
  39.    FilterOutput(OutputIterator out, Predicate pred)
  40.    { return FilteringOutputIterator<T, OutputIterator, Predicate>(out, pred); }
  41. }
  42. int main()
  43. {
  44.   const int integers[] = {1, 2, 3, 4, 5, 6};
  45.   // j'utilise la liste pour te faire plaisir, sinon y en a pas besoin
  46.   // autant tout sortir sur std::cout
  47.   typedef std::list<int> Liste;
  48.   Liste res;
  49.   std::copy(&integers[0],
  50.     &integers[0] + sizeof integers / sizeof integers[0],
  51.     FilterOutput<Liste::value_type>(std::back_inserter(res),
  52.         selector<Liste::value_type> )
  53.     );
  54.   std::copy(res.begin(), res.end(),
  55.     std::ostream_iterator< Liste::value_type >(std::cout, ", " ));
  56.   std::cout << std::endl;
  57. }


Message édité par Taz le 22-06-2004 à 07:52:13
n°772267
xterminhat​e
Si vis pacem, para bellum.
Posté le 22-06-2004 à 07:21:18  profilanswer
 

Merci pour l'exemple. C'est instructif.


---------------
Cordialement, Xterm-in'Hate...
n°772482
HelloWorld
Salut tout le monde!
Posté le 22-06-2004 à 11:34:53  profilanswer
 

Taz a écrit :

Code :
  1. template<typename InputIterator,
  2.    typename OutputIterator,
  3.    typename Predicate>
  4.   inline void copy_if(InputIterator first, InputIterator last,
  5.        OutputIterator out,
  6.        Predicate p)
  7.   {
  8.     while(first != last)
  9.       {
  10. if( p(*first) )
  11.   {
  12.     *out++ = *first;
  13.   }
  14. ++first;
  15.       }
  16.   }




La version Stroustrup retourne out à la fin et pas void.


Message édité par HelloWorld le 22-06-2004 à 11:35:10

---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°775166
Taz
bisounours-codeur
Posté le 24-06-2004 à 07:39:40  profilanswer
 

ça me fait une belle jambe ... surtout si tu crois que j'ai besoin d'un livre ou d'une quelconque documentation pour écrire ce genre de chose ...

n°776959
xterminhat​e
Si vis pacem, para bellum.
Posté le 24-06-2004 à 21:53:40  profilanswer
 

Comment se passer de l'appel back_inserter() en argument de copy_if ?
 
Est-ce que passer l'iterateur en référence et fournir un iterateur à l'aide de begin() conviendrait ?


---------------
Cordialement, Xterm-in'Hate...
n°776980
Taz
bisounours-codeur
Posté le 24-06-2004 à 21:58:13  profilanswer
 

non. il faut fournir un itérateur d'insertion un back/front/<rien> inserter doit donc être utilisé

n°777255
HelloWorld
Salut tout le monde!
Posté le 25-06-2004 à 00:05:15  profilanswer
 

Taz a écrit :

ça me fait une belle jambe ... surtout si tu crois que j'ai besoin d'un livre ou d'une quelconque documentation pour écrire ce genre de chose ...


C'est pas ma faute si t'es nul en C++ [:spamafote]


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°777293
Taz
bisounours-codeur
Posté le 25-06-2004 à 00:33:04  profilanswer
 

désolé, j'ai rien pour relever

n°777339
farib
Posté le 25-06-2004 à 03:54:23  profilanswer
 

fight, fight

n°778036
HelloWorld
Salut tout le monde!
Posté le 25-06-2004 à 14:45:16  profilanswer
 

Taz a écrit :

désolé, j'ai rien pour relever


Ta réaction était tellement stupide que j'ai essayé de l'être encore plus. Ma réponse s'adressait à personne en particulier, c'était dans un but de précision. Maitenant si tu te vexe parce qu'on post une remarque sur ton code, t'as qu'à créer une catégorie Taz où y'a que toi qui a le droit de répondre. Ta susceptibilité à 2 balles tu peux te la garder.
C'est pas tout d'avoir le style grande gueule, faut pas venir pleurnicher quand ça t'arrives.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°778049
Taz
bisounours-codeur
Posté le 25-06-2004 à 15:02:49  profilanswer
 

:heink:  
je sais pas ou t'as vu que je pleurnichais... mais bon si ça t'amuse que penser que je suis un capricieux caractériel qui gueule sur les autres mais qui rentre pleurer chez ça mère dès qu'on lui quelque chose ...
 
d'ailleurs j'ai toujours pas compris ton intervention ...

n°779389
HelloWorld
Salut tout le monde!
Posté le 27-06-2004 à 01:04:42  profilanswer
 

Y'a rien à comprendre. Le but était de compléter ta réponse initiale.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°819881
xterminhat​e
Si vis pacem, para bellum.
Posté le 11-08-2004 à 01:30:30  profilanswer
 

J'ai adapté le code de copy_if pour réaliser un algo légèrement différent. Il s'agit cette fois de copier les éléments d'un conteneur vers un autre en fonction du type de leurs éléments.
 
Concrètement, je construit une list<D*> à partir des éléments d'une list<B*> si la conversion B* vers D* est possible.
 
Cela semble foncitonner correctement :
 

Code :
  1. template<typename T, typename InputIterator,typename OutputIterator>
  2. inline void transform_if_type(InputIterator first, InputIterator last, OutputIterator out)
  3. {
  4. while(first != last)
  5. {
  6.  if( T p = dynamic_cast<T>( *first ) ) 
  7.   *out++ = p;
  8.  ++first;
  9. }
  10. }


 
L'utilisation de cette algo est équivalente aux exemples précédents du post : transform_if_type<D*>( .., .., back.. );
 
Par contre, je me demande si je ne suis pas encore passé à coté d'un algo plus simple, plus évident.


Message édité par xterminhate le 11-08-2004 à 01:32:54
n°819897
Taz
bisounours-codeur
Posté le 11-08-2004 à 07:33:02  profilanswer
 

ça peut aller ça. sauf niveau typage, c'est un joyeux bordel pour deviner qui est qui, le problème étant que rien ne mets en relation OutputIterator et T, tu es donc obligé de le spécifier. donc veille bien à utilise ::value_type.  
 
transform_if_is_instance :P est plus correct
 
l'important ce que ça te satisfasse

n°820571
xterminhat​e
Si vis pacem, para bellum.
Posté le 11-08-2004 à 18:07:07  profilanswer
 

En reformulant qq peu les types, j'obtiens un algo assez spécialisé. Le compilateur refuse de templatiser le de conteneur, dommage! Sinon j'obtiens un warning du genre : `typename std::list<TB*, std::allocator<TB*>>::const_iterator' is implicitly a typename
 

Code :
  1. template< typename TB, typename TD, template < typename X > class C  >
  2. inline void transform_if_is_instance( typename C<TB*>::const_iterator first, typename C<TB*>::const_iterator last, back_insert_iterator< C<TD*> > out )
  3. {
  4. while(first != last)
  5. {
  6.  if( TD* p = dynamic_cast<TD*>( *first ) ) 
  7.   *out++ = p;
  8.  ++first;
  9. }
  10. }


--edit1 : correction warning / ajout de typename.
--edit2 : retrait spécialisation / ajout template template.


Message édité par xterminhate le 11-08-2004 à 19:29:18

---------------
Cordialement, Xterm-in'Hate...
n°820607
Taz
bisounours-codeur
Posté le 11-08-2004 à 18:27:30  profilanswer
 

utilise typename :o (voir mon topic)
 
bah y a pas besoin de restreindre a std::list :o

n°820665
xterminhat​e
Si vis pacem, para bellum.
Posté le 11-08-2004 à 19:12:14  profilanswer
 

ok pour typename.
 
Comment faire pour eviter la spécialisation ?


---------------
Cordialement, Xterm-in'Hate...
n°820674
Taz
bisounours-codeur
Posté le 11-08-2004 à 19:15:17  profilanswer
 

en déclarant un paramètre template template

n°820675
xterminhat​e
Si vis pacem, para bellum.
Posté le 11-08-2004 à 19:17:33  profilanswer
 

C'est bien ce dont j'ai besoin ! Je ne pensais pas que c'etait possible... je vais essayer de trouver.


---------------
Cordialement, Xterm-in'Hate...
n°820678
Taz
bisounours-codeur
Posté le 11-08-2004 à 19:20:42  profilanswer
 

template< template<typename T> class Sequence >

n°820685
xterminhat​e
Si vis pacem, para bellum.
Posté le 11-08-2004 à 19:28:49  profilanswer
 

Voila ! Dans le template template, typename ne peut pas être utilisé...bizarre.


---------------
Cordialement, Xterm-in'Hate...
n°820712
cricri_
Posté le 11-08-2004 à 20:01:47  profilanswer
 

Je suis impresionné ... ;)
Un jour j'y arriverai à comprendre comment fonctionne les templates !  :ange:  
Enfin peut-être ..  :lol:  

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  (STL) algo copy_if

 

Sujets relatifs
algo du calcul formel du determinant matrice symetrique pas positiveEcrire mon propre parser xml a base des STL en c++
[Algo] Logiciel pour taper ses algo très proprement[Algo] Calcul des points d'une partie de bowling
[algo] Recherche du plus long chemin[Algo] Formulaire HTML ou intégré à l'appli ?
[ALGO] Afficher un arbre de manière optimaleAlgo cycle de graph
[STL] pb avec les map - core dumped dès que l'on fait un ajout[algo] approximation du sinus : on va jusqu'a quel ordre ?
Plus de sujets relatifs à : (STL) algo copy_if


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR