Home c++ Function random_shuffle (first, last, random)

Function random_shuffle (first, last, random)

Author

Date

Category

C++ has a function that shuffles the random_shuffle () sequence. Typically, it is used with two arguments.
However, there is a three-argument version.

How to use it with these three arguments?

The third argument is the “random number generator function”. In theory, this third argument is a functor. Just which one? The instructions say that this functor should return for n elements a value in the range [0, n] .

I tried to write something like a functor. Compiles but doesn’t work. Runtime error. Here is the code:

using namespace std;
  template & lt; class T & gt;
  class Func {
    T num;
  public:
    Func (T & amp; a)
      : num (a)
    {}
    T & amp; operator () (T & amp; x)
    {x = (T) ((rand ())% (int) x);
      return x;}
  };
const int NUM = 12;
int main (void)
{
  int sz = NUM;
  vector & lt; int & gt; vec;
  int i = 0;
  for (i = 0; i & lt; NUM; ++ i)
    vec.push_back (rand ());
  int g = sz-1;
  Func & lt; int & gt; f (g);
  random_shuffle (vec.begin (), vec.end (), f);
// A runtime error occurs here.
return 0;
}

Showing what I did

{
# include & lt; iostream & gt;
# include & lt; vector & gt;
# include & lt; set & gt;
# include & lt; ctime & gt;
# include & lt; algorithm & gt;
# include & lt; functional & gt;
using namespace std;
// Functor (undercut). But a worker !!!
// This is a BAD Functor !!!
// It CANNOT be applied WITHOUT MANDATORY
// specifying the Argument.
  template & lt; class T & gt;
  class Func_1 {
    T num;
  public:
    Func_1 (const T & amp; a)
      : num (a)
    {}
    T operator () (const T & amp; x) {return rand ()% x;}
    // IT WORKED!!!
  };
// This Functor works ONLY for TYPE "int" !!!
  class Func_2
  {
  public:
    int operator () (const int & amp; x)
    {
      return rand ()% x;
    }
  };
// This is how a NORMAL Functor should look like !!!
  template & lt; class T & gt;
  class Func_3: unary_function & lt; T, T & gt;
  {
  public:
    T operator () (T & amp; x)
    {
      return (T) rand ()% x;
    }
  };
  // Constant for the NUMBER of Cycles.
  const int NUM = 12;
int main (void)
{
  cout & lt; & lt; "\ n \ n \ tBEGIN !!! \ n \ n" & lt; & lt; endl;
  srand ((int) time (0));
  vector & lt; int & gt; vec_base, vec_1, vec_2, vec_3;
  set & lt; int & gt; s_temp;
  while (s_temp.size () & lt; NUM + 1)
    s_temp.insert (rand ()% 100);
  set & lt; int & gt; :: iterator sb = s_temp.begin ();
  while (sb! = s_temp.end ())
  {
    vec_base.push_back (* sb);
    vec_1.push_back (* sb);
    vec_2.push_back (* sb);
    vec_3.push_back (* sb);
    ++ sb;
  }
  cout & lt; & lt; "\ n \ tSORT VEC_base: \ n" & lt; & lt; endl;
  vector & lt; int & gt; :: iterator vb = vec_base.begin ();
  int v = 0;
  for (v = 0; v & lt; NUM; ++ v)
  {
    cout & lt; & lt; "\ t" & lt; & lt; v + 1 & lt; & lt; "." & lt; & lt; * vb & lt; & lt; endl;
    ++ vb;
  }
  cout & lt; & lt; "\ t \ tRANDOM_SHUFFLE (1,2): \ n \ n" & lt; & lt; endl;
  cout & lt; & lt; "\ n \ n \ tNOT SORT VEC_base: \ n" & lt; & lt; endl;
  random_shuffle (vec_base.begin (), vec_base.end ());
  vb = vec_base.begin ();
  v = 0;
  for (v = 0; v & lt; NUM; ++ v)
  {
    cout & lt; & lt; "\ t" & lt; & lt; v + 1 & lt; & lt; "." & lt; & lt; * vb & lt; & lt; endl;
    ++ vb;
  }
  cout & lt; & lt; "\ n \ t \ tRANDOM_SHUFFLE (1,2,3): \ n" & lt; & lt; endl;
// This should only be done for a BAD Functor !!!
// This BAD Functor DEMANDS an Argument !!!
  int g = NUM;
  Func_1 & lt; int & gt; f (g);
// This will not work !!!
// NORMAL Functors MUST NOT be their own Arguments !!!
// Their Arguments are initialized by Algorithms !!!
// Func_2ft (g);
// Func_3 & lt; int & gt; fn (g);
// This is a BAD Functor. It cannot be applied without an argument !!!
  random_shuffle (vec_1.begin (), vec_1.end (), Func_1 & lt; int & gt; (g)); 
// Normal Functors should be used WITHOUT Argument !!!
  random_shuffle (vec_2.begin (), vec_2.end (), Func_2 ());
  random_shuffle (vec_3.begin (), vec_3.end (), Func_3 & lt; int & gt; ());
  vb = vec_1.begin ();
  cout & lt; & lt; "\ n \ n \ tNOT SORT VEC_1: \ n" & lt; & lt; endl;
  v = 0;
  for (v = 0; v & lt; NUM; ++ v)
  {
    cout & lt; & lt; "\ t" & lt; & lt; v + 1 & lt; & lt; "." & lt; & lt; * vb & lt; & lt; endl;
    ++ vb;
  }
  vb = vec_2.begin ();
  cout & lt; & lt; "\ n \ n \ tNOT SORT VEC_2: \ n" & lt; & lt; endl;
  v = 0;
  for (v = 0; v & lt; NUM; ++ v)
  {
    cout & lt; & lt; "\ t" & lt; & lt; v + 1 & lt; & lt; "." & lt; & lt; * vb & lt; & lt; endl;
    ++ vb;
  }
  vb = vec_3.begin ();
  cout & lt; & lt; "\ n \ n \ tNOT SORT VEC_3: \ n" & lt; & lt; endl;
  v = 0;
  for (v = 0; v & lt; NUM; ++ v)
  {
    cout & lt; & lt; "\ t" & lt; & lt; v + 1 & lt; & lt; "." & lt; & lt; * vb & lt; & lt; endl;
    ++ vb;
  }
  v = 0;
  cout & lt; & lt; "\ n \ n \ tEND !!! \ n \ n" & lt; & lt; endl;
return (0);
}
}

Answer 1, authority 100%

According to documentation , the implementation of the random_shuffle function might look like like this:

template & lt; class RandomAccessIterator, class RandomNumberGenerator & gt;
 void random_shuffle (RandomAccessIterator first, RandomAccessIterator last,
            RandomNumberGenerator & amp; gen)
{
 iterator_traits & lt; RandomAccessIterator & gt; :: difference_type i, n;
 n = (last-first);
 for (i = n-1; i & gt; 0; --i) {
  swap (first [i], first [gen (i + 1)]);
 }
}

From this example it follows that the function (functor class) gen should have approximately the following signature:

int your_function (int) // function
class Your_class // functor
{
 public:
  int operator () (int);
}

The function takes as input the maximum possible position of the element – i.e. the size of the collection, and returns the new position, which must have a value between 0 and the value of the accepted argument.

In its simplest form, the implementation is as follows:

int myrandom (int i) {return rand ()% i;}

Answer 2

My problem was that I was trying to assign my own argument to the functor, while the algorithm using the functor does it on its own.
BY THE WAY. The random_shuffle () algorithm not only shuffles the sequence, but also changes the value of one of its members. IT’S WEIRD.

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions