Saturday, May 19, 2012

Random vector

Last post it was about lambdas but, indeed, I just focused with an utility; random vectors creation. Now, after still being researching I found more intuitive and elegant forms.

Let's see this amazing things:



#include <algorithm>
#include <iostream>
#include <vector>
#include <time.h>

//Start reading inside main!!!!
//first template is the rank of numbers we want
//second, where it starts
template<int N, int Start = 0>
class MyRand{
public:
     int operator()(void){
         return std::rand()%N + Start;
     }
};

int fRand(){
     return std::rand()%10 + 30;
}

int main()
{
      // Create a vector object that contains 10 elements.
      std::vector<int> a(10);

     // randomly initialize using lambda expressions
     srand((unsigned)time(0)); 

     //generating the vector by means of standard random function
     //This is nice but you don't have much control of which rank of numbers
     //will be returned. Indeed, you know, with the macro RAND_MAX
     //and this is a huge number.

     //And that perhaps isn't what we expected. So the solucion is to use
     //a custom function:
     std::generate(a.begin(), a.end(), std::rand );

     //Now, just changing fRand we can get our wished numbers, but
     //even that is not the best way because you can't use any function
     //that takes some parameter and then you'd need as many function
     //as you need; and that can be tedious. Instead of this, we can use templates
     //which we won't get that problem.
     std::generate(a.begin(), a.end(), fRand );

     //So, here we go:
     //With two templated parameters we can get any random rank of numberes we want.
     //for example, if we want numbers between 10 and 20 that's the example:
     std::generate(a.begin(), a.end(), MyRand<10,10>() );

     //O maybe we want numbers between 14 and 71
     //how many numbers there are between them? 71 - 14 = 57 and we start at 14
     //So:
     std::generate(a.begin(), a.end(), MyRand<57,14>() );


     //like last time, how to write this vector with just code a line
     std::for_each(a.begin(), a.end(), [](int a){ std::cout << a << std::endl; } );
     return 0;
}


Sunday, May 13, 2012

Lambdas

Yes, I'm still alive hehe
Today, I have been working with C++11 and I did some awesome things.

In this post, I won't explain much, just because I'm still inexperienced but I will.

How many times did you print a vector? And how many lines was needed? Yes, of course. You could make a function but so many times you are just debuging and you aren't really interested with it because you are solving anothers problems of mayor importance.

Here, there's an example with one line to do it. Moreover, I randomly initialized the vector with the same idea.

#include <algorithm>
#include <iostream>
#include <vector>
#include <time.h>

using namespace std;

int main()
{
    // Create a vector object that contains 10 elements.
    vector<int> a(10);

    // randomly initialize using lambda expressions
    srand((unsigned)time(0)); 
    for_each(a.begin(), a.end(), [](/*by reference*/ int& aux){
        aux = rand()%100; } );

    //now, print it
    for_each(a.begin(), a.end(), [](int aux){ cout << aux << endl; } );

    return 0;
}


If you are not used to use for_each, here is an example without use lambdas:

#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

void printThing(int i){
     cout << i << endl;
}

int main(){
    // Create a vector object that contains 10 elements.
    vector<int> a(10);

    // randomly initialize using lambda expressions
    srand((unsigned)time(0)); 
    for_each(a.begin(), a.end(), [](int& aux){aux = rand()%100; } );

    for_each(a.begin(), a.end(), printThing );
    return 0;
}


And another example using templates, just getting fun:

#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

template<class T>
void printThing(T i){ //void printThing(const T& i) would be better/faster
     cout << i << endl;
}

int main(){
    // Create a vector object that contains 10 elements.
    vector<int> a(10);

    // randomly initialize using lambda expressions
    srand((unsigned)time(0)); 
    for_each(a.begin(), a.end(), [](int& aux){aux = rand()%100; } );

    for_each(a.begin(), a.end(), printThing<char> );//yes is char, 
    //just to show that we are casting
    return 0;
}