洗牌算法

洗牌算法在笔试面试中出现过几次了,之前想的方法都不太好,而且实现也较复杂。看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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值