我在Coding Horror上读过一篇关于各种shuffle算法的文章.我已经看到人们已经在某个地方对列表进行了洗牌:
var r = new Random();
var shuffled = ordered.OrderBy(x => r.Next());
Run Code Online (Sandbox Code Playgroud)
这是一个很好的shuffle算法吗?它是如何工作的?这样做是否可以接受?
请建议一种最简单的方法,从具有'N'项的集合中获取计数'n'的随机混洗集合.其中n <= N
经典的Fisher Yates看起来像这样:
void shuffle1(std::vector<int>& vec)
{
int n = vec.size();
for (int i = n - 1; i > 0; --i)
{
std::swap(vec[i], vec[rand() % (i + 1)]);
}
}
Run Code Online (Sandbox Code Playgroud)
昨天,我错误地"向后"实现了迭代:
void shuffle2(std::vector<int>& vec)
{
int n = vec.size();
for (int i = 1; i < n; ++i)
{
std::swap(vec[i], vec[rand() % (i + 1)]);
}
}
Run Code Online (Sandbox Code Playgroud)
这个版本是否比第一个版本更糟(或更好)?它是否会扭曲由此产生的概率?