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

    题目:《程序员面试金典(第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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值