1.从100张牌里随机抽一张,这很简单吧,rand随机就行了。
2.从100张牌中抽50张牌,要求不重复呢。最简单的思路就是反复rand,并且将rand存入到hash表中,如果重复就在来一次,直到50次不重复。
3.从100张牌中抽99张不同的牌呢,那2的思路就很困难了,越到后面重复的概率越大,越耗时间。
接下来就到洗牌算法登场了。
这个算法的核心思路就是:将最后一个数和前面任意 n-1 个数中的一个数进行交换(也可以不换),然后倒数第二个数和前面任意 n-2 个数中的一个数进行交换,如此往复直到最后一个元素,就完成了洗牌,该算法保证了每个元素在每个位置的概率都是相等的。
我们举例子来说明:1,2,3,4,5
第一次交换,1,2,3,4,5出现在第五个位置的概率为1/5。假设我们交换的是2,序列变为1,5,3,4,2。
第二次交换,1,5,3,4出现在第四个位置的概率为1/4,同时第一次没有选中他们的概率为4/5,所以最后的概率还是1/5。假设交换的序列为4,5,3,1。
第三次交换,4,5,3出现在第三个位置的概率为1/3,同时需要乘上第一次没被选中和第二次没被选中的概率,分别为4/5和3/4。最后概率还是1/5。
相信后面不需要推演了,大家应该都能知道这个算法的厉害之处了。
代码:
for(int i = n-1; i >= 0 ; --i){ swap(arr[i],arr[rand()%(i+1)]); }
洗牌的速度是o(n)哦。
标签:rand,概率,洗牌,交换,张牌,算法 来源: https://www.cnblogs.com/suppersam/p/16161009.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。