洗牌算法

来源:互联网 发布:网络推广有哪些方式 编辑:程序博客网 时间:2024/05/20 01:38

洗牌算法在笔试面试中出现过几次了,之前想的方法都不太好,而且实现也较复杂。看STL源码剖析才知道STL里提供了一个将容器元素打乱重排的算法random_shuffle(),算法的实现很简单,下面是源代码:

  /**   *  @brief Shuffle the elements of a sequence using a random number   *         generator.   *  @ingroup mutating_algorithms   *  @param  first   A forward iterator.   *  @param  last    A forward iterator.   *  @param  rand    The RNG functor or function.   *  @return  Nothing.   *   *  Reorders the elements in the range @p [first,last) using @p rand to   *  provide a random distribution. Calling @p rand(N) for a positive   *  integer @p N should return a randomly chosen integer from the   *  range [0,N).  */  template<typename _RandomAccessIterator, typename _RandomNumberGenerator>    void    random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,   _RandomNumberGenerator& __rand)    {      // concept requirements      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<    _RandomAccessIterator>)      __glibcxx_requires_valid_range(__first, __last);      if (__first == __last)return;      for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)std::iter_swap(__i, __first + __rand((__i - __first) + 1));    }


要将向量vector<int> ivec中的元素打乱,调用random_shuffle(ivec.begin(), ivec.end())即可。

参考该算法的实现,可以很简单的写出洗牌算法:

void Show(int *arr){    for (int i = 1; i <= 54; i++)        cout << arr[i] << ends;    cout << endl;}int main(){    int arr[55] = {0}; //代表扑克牌的数组    for (int i = 1; i <= 54; i++)        arr[i] = i;    Show(arr);    srand(time(0));    int first = 1;    int last = 55;    for (int i = first + 1; i != last; i++)    {        swap(arr[i], arr[first + rand() % ((i - first) + 1)]);    }    //random_shuffle(arr + 1, arr + 55);  //和直接调用STL中的random_shuffle()算法是一样的效果    Show(arr);        return 0;}


原创粉丝点击