Archive

Posts Tagged ‘std::transform’

Functions for converting strings to upper/lower case

February 17, 2009 3 comments

Use following functions

  1. _strupr
  2. _strlwr
  3. std::transform – does the trick too but hard to understand
/* STRLWR.C: This program uses _strlwr and _strupr to create
 * uppercase and lowercase copies of a mixed-case string.
 */

#include <string .h>
#include <stdio .h>

void main( void )
{
   char str[100] = "The String to End All Strings!";
   printf( "Mixed: %s\n", str );
   printf( "Lower: %s\n", _strlwr( str ));
   printf( "Upper: %s\n", _strupr( str ));
}

// Output
// Mixed: The String to End All Strings!
// Lower: the string to end all strings!
// Upper: THE STRING TO END ALL STRINGS!

How about converting std::string to upper or lower case?

// Convert std::string to upper or lower case
std::string teststr = “Nibu Babu Thomas”;
_strlwr( &teststr[0] );
cout << endl << teststr.c_str() << endl; _strupr( &teststr[0] ); cout << teststr.c_str() << endl;[/sourcecode] How about converting 'CString' to upper or lower case? Fortunately and wisely enough there are member functions called 'MakeLower', 'MakeUpper'. Phew! [sourcecode language='cpp']CString csTest = _T( "Nibu Babu Thomas" ); csTest.MakeUpper();// Now in upper case csTest.MakeLower(); // Now in lower case[/sourcecode]

Advertisements

Using std transform function

So what does std::transform function do?

“Applies a specified function object to each element in a source range or to a pair of elements from two source ranges and copies the return values of the function object into a destination range.”

Some general applications of using transform is as follows…

  1. For doing some kind of operation on two vectors of same type and storing the result in a third vector.
  2. For doing some kind of in place operations on a vector.

So simplified prototypes of this function…

template<class InputIterator, class OutputIterator, class UnaryFunction>
OutputIterator transform( InputIterator _First1,
                          InputIterator _Last1,
                          OutputIterator _Result,
                          UnaryFunction _Func );
template</class><class InputIterator1, class InputIterator2, class OutputIterator, class BinaryFunction>
OutputIterator transform( InputIterator1 _First1,
                          InputIterator1 _Last1,
                          InputIterator2 _First2,
                          OutputIterator _Result,
                          BinaryFunction _Func );

So first prototype can take two different vectors or can be the same vector for inplace modification,while second one takes three, two source vectors (for e.g. two vector of ints and we add these two vectors and place the result in a third vector).

The applications of this function is powerful! Here are some demos

// Starts here
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
   void Demo_Std_TransformInplace();
   Demo_Std_TransformInplace();

   void Demo_Std_Transform_Binary();
   Demo_Std_Transform_Binary();

   return 0;
}

#include <vector> // for std::vector
#include <algorithm> // for std::transform

// Callbacks used with std::transform, can also be functors but for ease of calling //
// Unary operations. Note that I am alternating 'class' and 'typename' keywords just
// to prevent code formatting errors in HTML.
template<class T> T Square( const T Elem ) { return Elem * Elem; }
template<typename T> T ReverseSign( const T Elem ) { return -Elem; }
template<class T> T IncrementBy1( const T Elem ) { return Elem + 1; }
template<typename T> T DecrementBy1( const T Elem ) { return Elem - 1; }

// Binary operations
template<class T> T Add( const T Elem1, const T Elem2 ) { return Elem1 + Elem2; }
template<typename T> T Multiply( const T Elem1, const T Elem2 ) { return Elem1 * Elem2; }
template<class T> T Divide( const T Elem1, const T Elem2 ) { return Elem1 / Elem2; }
template<typename T> T Substract( const T Elem1, const T Elem2 ) { return Elem1 - Elem2; }

// A typedef for ease of use
typedef double VectorType; // Change this type and see the result
typedef std::vector<vectortype> VTVector; // Vector typedef
const VTVector::size_type Size = 1000; // Default size, increase to test performance

// Randomly fills in a vector
void FillInIntVector( VTVector& Vec )
{
   for( VTVector::size_type Index = 0; Index < Vec.size(); ++Index )
   {
      Vec&#91;Index&#93; = static_cast<VectorType>( rand() );
   }
}

// Functions for testing std::transform, Debug through and see the results //
void Demo_Std_TransformInplace()
{
   VTVector VTObj( Size );
   FillInIntVector( VTObj );

   // Do some in place operations
   std::transform( VTObj.begin(), VTObj.end(), VTObj.begin(), Square</vectortype><vectortype> );
   std::transform( VTObj.begin(), VTObj.end(), VTObj.begin(), ReverseSign</vectortype><vectortype> );
   std::transform( VTObj.begin(), VTObj.end(), VTObj.begin(), IncrementBy1</vectortype><vectortype> );
   std::transform( VTObj.begin(), VTObj.end(), VTObj.begin(), DecrementBy1</vectortype><vectortype> );
}

void Demo_Std_Transform_Binary()
{
   // Randomly fill in first vector
   VTVector VTObj1( Size );
   FillInIntVector( VTObj1 );   

   // Randomly fill in second vector
   VTVector VTObj2( Size );
   FillInIntVector( VTObj2 );

   // Added result will be placed in here
   VTVector Result( Size );

   // Add "VTObj1" and "VTObj2" vector place the result in "Result"
   std::transform( VTObj1.begin(), VTObj1.end(), VTObj2.begin(), Result.begin(), Add</vectortype><vectortype> );
   std::transform( VTObj1.begin(), VTObj1.end(), VTObj2.begin(), Result.begin(), Multiply</vectortype><vectortype> );  
   std::transform( VTObj1.begin(), VTObj1.end(), VTObj2.begin(), Result.begin(), Divide</vectortype><vectortype> );
   std::transform( VTObj1.begin(), VTObj1.end(), VTObj2.begin(), Result.begin(), Substract</vectortype><vectortype> );
}

Categories: C++, VC++ Tags: , , ,
%d bloggers like this: