一天一个算法: 随机洗牌算法

来源:互联网 发布:底层软件开发工程师 编辑:程序博客网 时间:2024/05/16 17:38
 洗牌算法是我们常见的随机问题,在玩游戏、随机排序时经常会碰到。它可以抽象成这样:得到一个M以内的所有自然数的随机顺序数组。 洗牌算法大多都是建立在随机数的基础上的,现在介绍几种随机数基础上的随机洗牌算法: (1)第一种可以简单描述成:随机抽牌,放在另一组;再次抽取,抽到空牌则重复抽。抽到空牌则重新抽的话,越到后面抽到空牌的几率就越大,所以显然是不合理的。我们可以进一步优化:拍抽走后,原牌变少,我们把抽走的牌之后的牌往前移一位,来填补空牌的空缺。代码如下:
   vector<int> shuffle_pick_1(size_t m) {      vector<int> vec1;      //生成m张牌      for(size_t i=0; i<m ; i++)        vec1.push_back(i);      vector<int> vec2;      for(size_t i=m; i>0; i--){        int rmd = floor(random()*i);        vec2.push_back(vec1[rmd]);          vec1.erase(vec1.begin()+rmd); //从原来的牌中删除空牌      }      return vec2;   }

这个也明显有问题,因为数组如果很大的话,删除中间的某个元素,会导致后面的排队向前走一步,这是一个很耗时的动作。
回想一下“我们为什么要删除那个元素?”目的就是为了不产生空牌。
除了删除那个元素之外,我们是不是还有其它方式来去除空牌?
—-有的,我们把最后一张未抽的牌放在那个抽走的位置上就可以了。
所以,这个思路我们可以优化成这样:
未完待续。。。

0 0
原创粉丝点击