I l@ve RuBoard Previous Section Next Section

Exercise 3.4

Write a program to read a sequence of integer numbers from standard input using an istream_iterator. Write the odd numbers into one file using an ostream_iterator. Each value should be separated by a space. Write the even numbers into a second file, also using an ostream_iterator. Each of these values should be placed on a separate line.

To read a sequence of integers from standard input, we define two istream_iterators: one bound to cin, and the second representing end-of-file.



istream_iterator<int> in( cin ), eos; 

Next, we define a vector to hold the elements read:



vector< int > input; 

To perform the reading, we use the copy() generic algorithm:



#include <iterator> 


#include <vector> 


#include <iostream> 


#include <algorithm> 


using namespace std; 





int main() 


{ 


   vector< int > input; 


   istream_iterator in( cin ), eos; 





   copy( in, eos, back_inserter( input )); 





   // ... 


} 

The back_inserter() is necessary because copy() uses the assignment operator to copy each element. Because input is empty, the first element assignment would cause an overflow error. back_inserter() overrides the assignment operator. The elements are now inserted using push_back().

We partition the elements into even and odd using the partition() generic algorithm and an even_elem function object that evaluates to true if the value is even:



class even_elem { 


public: 


   bool operator()( int elem ) 


        { return elem%2 ? false : true; } 


}; 





vector<int>::iterator division = 


     partition( input.begin(), input.end(), even_elem() ); 

We need two ostream_iterators: one for the even number file and one for the odd number file. We first open two files for output using the ofstream class:



#include <fstream> 


ofstream even_file( "C:\\My Documents\\even_file" ), 


          odd_file( "C:\\My Documents\\odd_file" ); 





if ( ! even_file || ! odd_file ) 


{ 


     cerr << "arghh!! unable to open the output files. bailing out!"; 


     return ?; 


} 

We bind our two ostream_iterators to the respective ofstream objects. The second string argument indicates the delimiter to output following the output of each element.



ostream_iterator<int> even_iter( even_file, "\n" ), 


                       odd_iter( odd_file, " " ); 

Finally, we use the copy() generic algorithm to output the partitioned elements:



copy( input.begin(), division, even_iter ); 


copy( division, input.end(), odd_iter ); 

For example, I entered the following sequence of numbers:



2 4 5 3 9 5 2 6 8 1 8 4 5 7 3 

At that point, even_file contained the following values: 2 4 4 8 8 6 2, whereas odd_file contained these values: 5 9 1 3 5 5 7 3. The partition() algorithm does not preserve the order of the values. If preserving the order of the values is important, we would instead use the stable_partition() generic algorithm. Both the stable_sort() and stable_partition() algorithms maintain the elements' relative order.

    I l@ve RuBoard Previous Section Next Section