【数学】彻底打乱数组中元素的次序

来源:互联网 发布:凯立德车载导航软件 编辑:程序博客网 时间:2024/05/07 10:02

    题目:《程序员面试金典(第5版)》P332

    编写一个函数,洗一副牌。要求做到完美洗牌,换言之,这副牌52! 种排列组合出现的概率相同。假设给定一个完美的随机数发生器。

    提示:问题实际上等价为彻底打乱某个数组。

    方法一:该方法和“蓄水池抽样算法”有类似之处。

void Swap(int &a,int &b){int temp=a;a=b;b=temp;}bool shuffleArrayInteratively(int* a,int len){if(a==nullptr || len<=0)return false;for(int i=1;i<len;i++){//PerfectRand()的作用是随机生成一个大于等于0、小于等于i的整数,由出题者提供int randnum = PerfectRand(i); Swap(a[randnum],a[i]);}return true;}

    方法二(更加简单明了)已随机序列从右向左扩大,未随机序列中随机选一个,与未随机序列的尾元素交换

 若要解决“从n个数中随机选出m个数”这个问题,则方法二中数组最后的m个数,就是随机选出的m个数。

bool shuffleArrayInteratively2(int* a,int len)  { if(a==nullptr || len<=0)          return false;   for(int i=len-1;i>0;i--)      { //PerfectRand()的作用是随机生成一个大于等于0、小于等于i的整数,由出题者提供        int randnum = PerfectRand(i);           swap(a[randnum],a[i]);      }      return true;  }


0 0
原创粉丝点击