Wednesday, 14 April 2010

C++ example of 'transform'

From the CPP Reference:
#include
  1. output_iterator transform( input_iterator start, input_iterator end, output_iterator result, UnaryFunction f );
  2. output_iterator transform( input_iterator start1, input_iterator end1, input_iterator2 start2, output_iterator result, BinaryFunction f );
The transform algorithm applies the function f to some range of elements, storing the result of each application of the function in result.

The first version of the function applies f to each element in [start,end) and assigns the first output of the function to result, the second output to (result+1), etc.

The second version of the transform works in a similar manner, except that it is given two ranges of elements and calls a binary function on a pair of elements.

Here is an example that is modified from C++ Reference:




//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Program to show how transform works in C++

#include<iostream>
#include<vector>
#include<algorithm> //for the transform() function

using namespace
std;

int
increase (int i) { return ++i; }
int
sum (int i, int j) { return i+j; }

int
main()
{

int
someNums[] = {10,20,30,40,50}; //Array of 5 values
//Another way to initialise a vector using the iterator constructor
vector<int> vectorOne (someNums, someNums + sizeof(someNums) / sizeof(int));
vector<int> vectorTwo;
vector<int>::iterator it;

cout<<"vectorOne elements are : ";
for
(unsigned int i = 0; i < vectorOne.size(); ++i)
cout<<vectorOne[i]<<" ";
cout<<endl;

vectorTwo.resize(vectorOne.size()); //allocate space

//OutputIterator transform ( InputIterator first1, InputIterator last1,
// OutputIterator result, UnaryOperator op );
std::transform(vectorOne.begin(), vectorOne.end(), vectorTwo.begin(), increase);

cout<<"\nAfter transform with increase:"<<endl;
cout<<"vectorOne elements are : ";
for
(unsigned int i = 0; i < vectorOne.size(); ++i)
cout<<vectorOne[i]<<" ";
cout<<endl;
cout<<"vectorTwo elements are : ";
for
(unsigned int i = 0; i < vectorTwo.size(); ++i)
cout<<vectorTwo[i]<<" ";
cout<<endl;

//OutputIterator transform ( InputIterator1 first1, InputIterator1 last1,
// InputIterator2 first2, OutputIterator result,
// BinaryOperator binary_op );
transform (vectorOne.begin(), vectorOne.end(), vectorTwo.begin(), vectorOne.begin(), sum);

cout<<"\nAfter transform with sum:"<<endl;
cout<<"vectorOne elements are : ";
for
(unsigned int i = 0; i < vectorOne.size(); ++i)
cout<<vectorOne[i]<<" ";
cout<<endl;
cout<<"vectorTwo elements are : ";
for
(unsigned int i = 0; i < vectorTwo.size(); ++i)
cout<<vectorTwo[i]<<" ";
cout<<endl;

return
0;
}





The output is as follows:

2 comments:

  1. Love this blog. Might I suggest for the output above that you use the following instead of the looping construct:

    std::copy( vectorOne.begin(), vectorOne.end(), std::ostream_iterator( std::cout, " " ) );

    ReplyDelete
  2. I would rather split the above in two lines for simple reading:

    ostream_iterator out_it (cout," ");
    copy( vectorOne.begin(), vectorOne.end(), out_it );

    But it makes the code less readable, especially for new starters.

    Also I am not sure if it gives any performance advantage.

    ReplyDelete