random_shuffle

//版本一:使用内部的随机数生成器 
template<class RandomAccessIterator> 
   void random_shuffle( 
      RandomAccessIterator _first,  
      RandomAccessIterator _last 
   )
{
  __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
  if (__first == __last) return;
  for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
    iter_swap(__i, __first + __random_number((__i - __first) + 1));
}
//版本二:是使用一个会产生随机数的仿函数
template<class RandomAccessIterator, class RandomNumberGenerator> 
   void random_shuffle( 
      RandomAccessIterator _first,  
      RandomAccessIterator _last,  
      RandomNumberGenerator& gen 
   )
{
    __STL_REQUIRES(_RandomAccessIter, _Mutable_RandomAccessIterator);
  if (__first == __last) return;
  for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
    iter_swap(__i, __first + __rand((__i - __first) + 1));

}

  随机重排[first,last)中的数据,有N!中可能,N=last-first,此算法会产生一种均匀分布任何特定排列顺序被选中的几率为1/N!版本二是一种特别的function object,当被引数传进来,传递方式是by reference,而不是by value,因为RandomNumberGenerator的重要特点是具有局部状态,每次被调用时被改变。

  使用乱数时,能够明白设定乱数产生器的种子是非常重要的,如果这对程序重要,则使用第二个版本。

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <ctime>
using namespace std;

class F
{
    public:
        ptrdiff_t operator()(ptrdiff_t max)
        {
            srand((unsigned)time(NULL));
            int _rand=static_cast<int>(rand()/static_cast<int>(RAND_MAX));
            return static_cast<ptrdiff_t>(_rand*max);
        }    
};
int main()
{
    vector<int> v{1,2,3,4,5,6};
    
    random_shuffle(v.begin(),v.end(),F());
    for_each(v.begin(),v.end(),[](int i)
    {
        cout<<i<<" ";
    });
    cout<<endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/tianzeng/p/10386217.html