copying elements from a <list> to <deque> | |
It works fine. any advice on making it better or if I can
improve my C++ coding skills:
/* C++ Primer - 4/e
*
* Chapter 9 - Sequential Containers
* exercise 9.18 - STATEMENT
* Write a program to copy elements from a list of "ints"
* to 2 "deques". The list elements that are even should go into one deque
* and even elements should go into 2nd deque.
*
*/
#include <iostream>
#include <list>
#include <deque>
#include <algorithm>
#include <iterator>
int main()
{
std::cout << "enter some integers: ";
std::list<intilist;
/* copy elements from std::cin into ilist */
std::copy( (std::istream_iterator<int>( std::cin )),
(std::istream_iterator<int>()),
std::back_inserter( ilist ) );
std::deque<intdeque_of_evens;
std::deque<intdeque_of_odds;
/* copy even elements into 1 deque and odds into the other */
for( std::list<int>::const_iterator iter = ilist.begin();
iter != ilist.end();
++iter)
{
if( *iter % 2 == 0 )
{
deque_of_evens.push_back( *iter );
}
else
{
deque_of_odds.push_back( *iter );
}
}
std::cout << "\n Printing Deque of Even Integers: ";
std::copy( deque_of_evens.begin(),
deque_of_evens.end(),
std::ostream_iterator<int>( std::cout, " " ) );
std::cout << "\n\n Printing Deque of Odd Integers: ";
std::copy( deque_of_odds.begin(),
deque_of_odds.end(),
std::ostream_iterator<int>( std::cout, " " ) );
std::cout << std::endl;
return 0;
}
-- http://lispmachine.wordpress.com | | | | re: copying elements from a <list> to <deque>
On 2007-09-25 09:59, arnuld wrote: Quote:
It works fine. any advice on making it better or if I can
improve my C++ coding skills:
>
/* C++ Primer - 4/e
*
* Chapter 9 - Sequential Containers
* exercise 9.18 - STATEMENT
* Write a program to copy elements from a list of "ints"
* to 2 "deques". The list elements that are even should go into one deque
* and even elements should go into 2nd deque.
*
*/
>
#include <iostream>
#include <list>
#include <deque>
#include <algorithm>
#include <iterator>
>
int main()
{
std::cout << "enter some integers: ";
std::list<intilist;
/* copy elements from std::cin into ilist */
std::copy( (std::istream_iterator<int>( std::cin )),
(std::istream_iterator<int>()),
std::back_inserter( ilist ) );
>
std::deque<intdeque_of_evens;
std::deque<intdeque_of_odds;
/* copy even elements into 1 deque and odds into the other */
for( std::list<int>::const_iterator iter = ilist.begin();
iter != ilist.end();
++iter)
{
if( *iter % 2 == 0 )
{
deque_of_evens.push_back( *iter );
}
else
{
deque_of_odds.push_back( *iter );
}
}
>
>
>
std::cout << "\n Printing Deque of Even Integers: ";
std::copy( deque_of_evens.begin(),
deque_of_evens.end(),
std::ostream_iterator<int>( std::cout, " " ) );
>
std::cout << "\n\n Printing Deque of Odd Integers: ";
std::copy( deque_of_odds.begin(),
deque_of_odds.end(),
std::ostream_iterator<int>( std::cout, " " ) );
>
std::cout << std::endl;
>
return 0;
}
You should research the (IMO badly named) remove_copy_if algorithm and
create a predicate to determine if the element is even or not.
--
Erik Wikström | | | | re: copying elements from a <list> to <deque>
Erik Wikström wrote: Quote:
On 2007-09-25 09:59, arnuld wrote: Quote:
>It works fine. any advice on making it better or if I can
>improve my C++ coding skills:
>>
>/* C++ Primer - 4/e
> *
> * Chapter 9 - Sequential Containers
> * exercise 9.18 - STATEMENT
> * Write a program to copy elements from a list of
> "ints" * to 2 "deques". The list elements that are even should go into
> one deque * and even elements should go into 2nd deque.
> *
> */
>>
>#include <iostream>
>#include <list>
>#include <deque>
>#include <algorithm>
>#include <iterator>
>>
>int main()
>{
> std::cout << "enter some integers: ";
> std::list<intilist;
> /* copy elements from std::cin into ilist */
> std::copy( (std::istream_iterator<int>( std::cin )),
>(std::istream_iterator<int>()),
>std::back_inserter( ilist ) );
>>
> std::deque<intdeque_of_evens;
> std::deque<intdeque_of_odds;
> /* copy even elements into 1 deque and odds into the other */
> for( std::list<int>::const_iterator iter = ilist.begin();
> iter != ilist.end();
> ++iter)
> {
> if( *iter % 2 == 0 )
>{
>deque_of_evens.push_back( *iter );
>}
> else
>{
>deque_of_odds.push_back( *iter );
>}
> }
>>
>>
>>
> std::cout << "\n Printing Deque of Even Integers: ";
> std::copy( deque_of_evens.begin(),
>deque_of_evens.end(),
>std::ostream_iterator<int>( std::cout, " " ) );
>>
> std::cout << "\n\n Printing Deque of Odd Integers: ";
> std::copy( deque_of_odds.begin(),
>deque_of_odds.end(),
>std::ostream_iterator<int>( std::cout, " " ) );
>>
> std::cout << std::endl;
>>
> return 0;
>}
>
You should research the (IMO badly named) remove_copy_if algorithm and
create a predicate to determine if the element is even or not.
And: you should implement the missing (sic!) copy_if algorithm and use the
same predicate for the other copy job.
Best
Kai-Uwe Bux | | | | re: copying elements from a <list> to <deque>
On Sep 25, 11:24 am, Kai-Uwe Bux <jkherci...@gmx.netwrote: Quote:
Erik Wikström wrote: Quote:
On 2007-09-25 09:59, arnuld wrote: Quote:
It works fine. any advice on making it better or if I can
improve my C++ coding skills:
Quote: Quote: Quote:
/* C++ Primer - 4/e
*
* Chapter 9 - Sequential Containers
* exercise 9.18 - STATEMENT
* Write a program to copy elements from a list of
"ints" * to 2 "deques". The list elements that are even should go into
one deque * and even elements should go into 2nd deque.
*
*/
Quote: Quote: Quote:
#include <iostream>
#include <list>
#include <deque>
#include <algorithm>
#include <iterator>
Quote: Quote: Quote:
int main()
{
std::cout << "enter some integers: ";
std::list<intilist;
/* copy elements from std::cin into ilist */
std::copy( (std::istream_iterator<int>( std::cin )),
(std::istream_iterator<int>()),
std::back_inserter( ilist ) );
Quote: Quote: Quote:
std::deque<intdeque_of_evens;
std::deque<intdeque_of_odds;
/* copy even elements into 1 deque and odds into the other */
for( std::list<int>::const_iterator iter = ilist.begin();
iter != ilist.end();
++iter)
{
if( *iter % 2 == 0 )
{
deque_of_evens.push_back( *iter );
}
else
{
deque_of_odds.push_back( *iter );
}
You might replace the if with:
(*iter % 2 == 0 ? deque_of_evens :
deque_of_odds).push_back( *iter ) ;
Opinions about this vary; I tend not to use ?: very much for
lvalues, but in this case, it does draw attention to the fact
that *all* of the elements end up in one of the two deques. Quote: Quote: Quote:
std::cout << "\n Printing Deque of Even Integers: ";
std::copy( deque_of_evens.begin(),
deque_of_evens.end(),
std::ostream_iterator<int>( std::cout, " " ) );
Quote: Quote: Quote:
std::cout << "\n\n Printing Deque of Odd Integers: ";
std::copy( deque_of_odds.begin(),
deque_of_odds.end(),
std::ostream_iterator<int>( std::cout, " " ) );
Quote: Quote: Quote:
std::cout << std::endl;
return 0;
}
Quote: Quote:
You should research the (IMO badly named) remove_copy_if
algorithm and create a predicate to determine if the element
is even or not.
Quote:
And: you should implement the missing (sic!) copy_if algorithm
and use the same predicate for the other copy job.
I'm not sure that I agree with either of these recommendations.
Both smack of obfuscation, and forcing things just to use a
standard (or non-standard, in the case of copy_if) algorithm.
For a more experienced programmer, I might consider a
boost::filter_iterator, e.g.:
std::deque< int evens(
boost::make_filter_iterator< IsEven >( ilist.begin(),
ilist.end() ),
boost::make_filter_iterator< IsEven >( ilist.end(),
ilist.end() ) ) ;
std::deque< int odds(
boost::make_filter_iterator< IsOdd >( ilist.begin(),
ilist.end() ),
boost::make_filter_iterator< IsOdd >( ilist.end(),
ilist.end() ) ) ;
This allows correct initialization; it would even allow making
evens and odds const. But it still requires moving the test out
of the loop, and even out of the function. And I'm pretty sure
that it's not the intent of the exercise.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 | | | | re: copying elements from a <list> to <deque>
On Sep 25, 2:56 pm, James Kanze <james.ka...@gmail.comwrote: Quote:
You might replace the if with:
>
(*iter % 2 == 0 ? deque_of_evens :
deque_of_odds).push_back( *iter ) ;
>
Opinions about this vary; I tend not to use ?: very much for
lvalues, but in this case, it does draw attention to the fact
that *all* of the elements end up in one of the two deques.
that's nice James (as for as my exercise is concerned ). I have
used that construct, it make my solution look clean :-) | | | | re: copying elements from a <list> to <deque>
James Kanze wrote: Quote:
On Sep 25, 11:24 am, Kai-Uwe Bux <jkherci...@gmx.netwrote: Quote:
>Erik Wikström wrote: Quote:
On 2007-09-25 09:59, arnuld wrote:
>It works fine. any advice on making it better or if I can
>improve my C++ coding skills:
> Quote: Quote:
>/* C++ Primer - 4/e
> *
> * Chapter 9 - Sequential Containers
> * exercise 9.18 - STATEMENT
> * Write a program to copy elements from a list of
> "ints" * to 2 "deques". The list elements that are even should go
> into one deque * and even elements should go into 2nd deque.
> *
> */
> Quote: Quote:
>#include <iostream>
>#include <list>
>#include <deque>
>#include <algorithm>
>#include <iterator>
> Quote: Quote:
>int main()
>{
> std::cout << "enter some integers: ";
> std::list<intilist;
> /* copy elements from std::cin into ilist */
> std::copy( (std::istream_iterator<int>( std::cin )),
>(std::istream_iterator<int>()),
>std::back_inserter( ilist ) );
> Quote: Quote:
> std::deque<intdeque_of_evens;
> std::deque<intdeque_of_odds;
> /* copy even elements into 1 deque and odds into the other */
> for( std::list<int>::const_iterator iter = ilist.begin();
> iter != ilist.end();
> ++iter)
> {
> if( *iter % 2 == 0 )
>{
>deque_of_evens.push_back( *iter );
>}
> else
>{
>deque_of_odds.push_back( *iter );
>}
>
You might replace the if with:
>
(*iter % 2 == 0 ? deque_of_evens :
deque_of_odds).push_back( *iter ) ;
>
Opinions about this vary; I tend not to use ?: very much for
lvalues, but in this case, it does draw attention to the fact
that *all* of the elements end up in one of the two deques.
> > Quote: Quote:
> std::cout << "\n Printing Deque of Even Integers: ";
> std::copy( deque_of_evens.begin(),
>deque_of_evens.end(),
>std::ostream_iterator<int>( std::cout, " " ) );
> Quote: Quote:
> std::cout << "\n\n Printing Deque of Odd Integers: ";
> std::copy( deque_of_odds.begin(),
>deque_of_odds.end(),
>std::ostream_iterator<int>( std::cout, " " ) );
> Quote: Quote:
> std::cout << std::endl;
> return 0;
>}
> Quote: Quote:
You should research the (IMO badly named) remove_copy_if
algorithm and create a predicate to determine if the element
is even or not.
> Quote:
>And: you should implement the missing (sic!) copy_if algorithm
>and use the same predicate for the other copy job.
>
I'm not sure that I agree with either of these recommendations.
Both smack of obfuscation, and forcing things just to use a
standard (or non-standard, in the case of copy_if) algorithm.
I have a great deal of sympathy for that sentiment. Functors tend to move
code from the place where you would like to see it to some other place.
That is generally not so good. Quote:
For a more experienced programmer, I might consider a
boost::filter_iterator, e.g.:
>
std::deque< int evens(
boost::make_filter_iterator< IsEven >( ilist.begin(),
ilist.end() ),
boost::make_filter_iterator< IsEven >( ilist.end(),
ilist.end() ) ) ;
std::deque< int odds(
boost::make_filter_iterator< IsOdd >( ilist.begin(),
ilist.end() ),
boost::make_filter_iterator< IsOdd >( ilist.end(),
ilist.end() ) ) ;
>
This allows correct initialization; it would even allow making
evens and odds const. But it still requires moving the test out
of the loop, and even out of the function.
[snip]
In a case like this, I like lambda:
std::remove_copy_if( ilist.begin(), ilist.end(),
std::back_inserter( deque_of_evens ),
_1 % 2 != 0 );
std::remove_copy_if( ilist.begin(), ilist.end(),
std::back_inserter( deque_of_odds ),
_1 % 2 == 0 );
(yet, I would prefer copy_if :-)
I agree, though, that cases where lambda is this concise are rare. But
compared to using std::binder..., std::modulus, ... lambda is great.
Best
Kai-Uwe Bux | | | | re: copying elements from a <list> to <deque>
On Sep 25, 3:23 pm, Kai-Uwe Bux <jkherci...@gmx.netwrote: Quote:
In a case like this, I like lambda:
>
std::remove_copy_if( ilist.begin(), ilist.end(),
std::back_inserter( deque_of_evens ),
_1 % 2 != 0 );
>
std::remove_copy_if( ilist.begin(), ilist.end(),
std::back_inserter( deque_of_odds ),
_1 % 2 == 0 );
>
ok, that's nice :)
and i did not get that _1 %2, I know it checks for even and odd
numbers but what exactly that "underscore 1" means: _1 %2 | | | | re: copying elements from a <list> to <deque>
arnuld wrote: Quote: Quote:
>On Sep 25, 3:23 pm, Kai-Uwe Bux <jkherci...@gmx.netwrote:
> Quote:
>In a case like this, I like lambda:
>>
> std::remove_copy_if( ilist.begin(), ilist.end(),
> std::back_inserter( deque_of_evens ),
> _1 % 2 != 0 );
>>
> std::remove_copy_if( ilist.begin(), ilist.end(),
> std::back_inserter( deque_of_odds ),
> _1 % 2 == 0 );
>>
>
ok, that's nice :)
>
and i did not get that _1 %2, I know it checks for even and odd
numbers but what exactly that "underscore 1" means: _1 %2
That's the magic of expression templates. If you are interested, you can
have a look at my posting http://groups.google.com/group/comp....422ea883a2b151
where I explain how one can about implementing something like that. Be
warned, however: it takes about 600 lines of code (and 300 lines of
comments) to make that _1 work (and that is just a proof of concept!).
Luckily, it already has been done and is in boost.
Best
Kai-Uwe Bux | | | | re: copying elements from a <list> to <deque>
On Sep 25, 2:56 pm, James Kanze <james.ka...@gmail.comwrote: Quote:
I'm not sure that I agree with either of these recommendations.
Both smack of obfuscation, and forcing things just to use a
standard (or non-standard, in the case of copy_if) algorithm.
For a more experienced programmer, I might consider a
boost::filter_iterator, e.g.:
>
std::deque< int evens(
boost::make_filter_iterator< IsEven >( ilist.begin(),
ilist.end() ),
boost::make_filter_iterator< IsEven >( ilist.end(),
ilist.end() ) ) ;
std::deque< int odds(
boost::make_filter_iterator< IsOdd >( ilist.begin(),
ilist.end() ),
boost::make_filter_iterator< IsOdd >( ilist.end(),
ilist.end() ) ) ;
>
This allows correct initialization; it would even allow making
evens and odds const. But it still requires moving the test out
of the loop, and even out of the function. And I'm pretty sure
that it's not the intent of the exercise.
I am trying this but can not copile my program with that without
errors. I am using remove_copy_if as suggested by Kai-Uwe Bux
(remember the _1 ;-)
but still I am interested in this use of boost library. I have copied
the code you wrote but then I am not able to get what to do to
make use of this make_filter_iterator.
any explanation ? | | | | re: copying elements from a <list> to <deque>
On Sep 25, 12:23 pm, Kai-Uwe Bux <jkherci...@gmx.netwrote: Quote:
James Kanze wrote:
[...] Quote: Quote: Quote:
And: you should implement the missing (sic!) copy_if algorithm
and use the same predicate for the other copy job.
Quote: Quote:
I'm not sure that I agree with either of these recommendations.
Both smack of obfuscation, and forcing things just to use a
standard (or non-standard, in the case of copy_if) algorithm.
Quote:
I have a great deal of sympathy for that sentiment. Functors
tend to move code from the place where you would like to see
it to some other place. That is generally not so good.
It depends. If you can supply a good, explicit name for the
function, and it is a "pure" function, not depending on any
local variables, it's not that bad. If you can reasonably
expect to use the function elsewhere, it's even good. I'd say
that his case meets the first criteron, but not really the
second. So it's not too bad, but I still prefer the test in an
explicit loop. (There's also the question of how much you're
throwing at the OP at a time. He IS working his way through a
tutorial text, and shouldn't be expected to handle everything at
once. Each thing in its time.) Quote: Quote:
For a more experienced programmer, I might consider a
boost::filter_iterator, e.g.:
Quote: Quote:
std::deque< int evens(
boost::make_filter_iterator< IsEven >( ilist.begin(),
ilist.end() ),
boost::make_filter_iterator< IsEven >( ilist.end(),
ilist.end() ) ) ;
std::deque< int odds(
boost::make_filter_iterator< IsOdd >( ilist.begin(),
ilist.end() ),
boost::make_filter_iterator< IsOdd >( ilist.end(),
ilist.end() ) ) ;
Quote: Quote:
This allows correct initialization; it would even allow
making evens and odds const. But it still requires moving
the test out of the loop, and even out of the function.
Quote:
In a case like this, I like lambda:
Quote:
std::remove_copy_if( ilist.begin(), ilist.end(),
std::back_inserter( deque_of_evens ),
_1 % 2 != 0 );
Quote:
std::remove_copy_if( ilist.begin(), ilist.end(),
std::back_inserter( deque_of_odds ),
_1 % 2 == 0 );
Quote:
(yet, I would prefer copy_if :-)
Quote:
I agree, though, that cases where lambda is this concise are
rare. But compared to using std::binder..., std::modulus, ...
lambda is great.
If we had a real lambda, it would be great (although as you
point out, in this particular case, boost::lambda works like a
real lambda). Ideally, even, we'd have a lambda which resolved
to a class which could be used to instantiate a template like
boost::make_filter_iterator, so I could replace IsEven and IsOdd
in my example.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 | | | | re: copying elements from a <list> to <deque>
On Sep 25, 8:11 pm, arnuld <geek.arn...@gmail.comwrote: Quote: Quote:
On Sep 25, 2:56 pm, James Kanze <james.ka...@gmail.comwrote:
I'm not sure that I agree with either of these recommendations.
Both smack of obfuscation, and forcing things just to use a
standard (or non-standard, in the case of copy_if) algorithm.
For a more experienced programmer, I might consider a
boost::filter_iterator, e.g.:
Quote: Quote:
std::deque< int evens(
boost::make_filter_iterator< IsEven >( ilist.begin(),
ilist.end() ),
boost::make_filter_iterator< IsEven >( ilist.end(),
ilist.end() ) ) ;
std::deque< int odds(
boost::make_filter_iterator< IsOdd >( ilist.begin(),
ilist.end() ),
boost::make_filter_iterator< IsOdd >( ilist.end(),
ilist.end() ) ) ;
Quote: Quote:
This allows correct initialization; it would even allow making
evens and odds const. But it still requires moving the test out
of the loop, and even out of the function. And I'm pretty sure
that it's not the intent of the exercise.
Quote:
I am trying this but can not copile my program with that without
errors. I am using remove_copy_if as suggested by Kai-Uwe Bux
(remember the _1 ;-)
Do you have Boost correctly installed? Are you including all of
the necessary Boost header files, and passing the necessary
options to the compiler so that it finds them (and the Boost
library, although I don't think either Kai-Uwe's suggestion or
mine actually require linking against the library). Quote:
but still I am interested in this use of boost library. I have
copied the code you wrote but then I am not able to get what
to do to make use of this make_filter_iterator.
The real explanation is that you're jumping too far ahead of
where you are in the learning cycle. Learn the basics first;
there's time enough for Boost later.
Other than that, of course, you have to ensure that Boost is
correctly installed, that the compiler is passed all of the
necessary options, etc. (Under Unix, for example, you'll need
at least an additional -I option, and perhaps also an additional
-l. With VC++, that's a /I option and an additional library to
link against.) But seriously: I prefixed my suggestion with
"For a more experienced programmer". I did so for a reason.
Don't worry about it yet.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 | | | | re: copying elements from a <list> to <deque>
On Wed, 26 Sep 2007 01:50:36 -0700, James Kanze wrote: Quote:
Do you have Boost correctly installed?
yes. Quote:
Are you including all of
the necessary Boost header files, and passing the necessary
options to the compiler so that it finds them (and the Boost
library, although I don't think either Kai-Uwe's suggestion or
mine actually require linking against the library).
don't know, I just used "#include <boost>" and GCC complained then. Quote:
The real explanation is that you're jumping too far ahead of
where you are in the learning cycle. Learn the basics first;
there's time enough for Boost later.
Quote:
But seriously: I prefixed my suggestion with
"For a more experienced programmer". I did so for a reason.
Don't worry about it yet.
Ok, I understood :-) for now, I will just use <algorithm>
-- arnuld http://lispmachine.wordpress.com | | | | re: copying elements from a <list> to <deque>
On 2007-09-28 15:39, arnuld wrote: Quote: Quote:
>On Wed, 26 Sep 2007 01:50:36 -0700, James Kanze wrote:
> Quote:
>Do you have Boost correctly installed?
>
yes.
> Quote:
>Are you including all of
>the necessary Boost header files, and passing the necessary
>options to the compiler so that it finds them (and the Boost
>library, although I don't think either Kai-Uwe's suggestion or
>mine actually require linking against the library).
>
don't know, I just used "#include <boost>" and GCC complained then.
I'm not a boost expert, but including <boostis probably not the right
way, you should include <boost/iterator/filter_iterator.hppand you
might need to include some other headers too.
--
Erik Wikström |  | | | | Forums
Visit our community forums for general discussions and latest on Bytes
/bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,582 network members.
|