算法一般也被称为洗牌算法,主要功能是将数组里的元素随机打乱,在扑克游戏及mp3播放器中比较常见。在C++的STL库中有专门的函数random_shuffle,在.net中就需要自己写了。不过这个算法并不复杂,一种常规写法如下:
static Random rnd = new Random();
public static IEnumerable<T> Shuffle<T>(IEnumerable<T> source)
{
var elements = source.ToArray();
for (int i = elements.Length - 1; i > 0; i--)
{
int swapIndex = rnd.Next(i + 1);
yield return elements[swapIndex];
elements[swapIndex] = elements[i];
}
yield return elements[0];
}
今天用google的时候发现了另一种写法:。
不过原文里面的写法还稍微麻烦了点,简化一下其实就一句话,使用的时候甚至都不用单独作为函数。
static IEnumerable<T> Shuffle<T>(IEnumerable<T> source)
{
return source.OrderBy(_ => rnd.Next());
}
当然,后面这种算法的效率上要差一点,但用到shuffle算法的时候一般是不会用到大数组的,性能差异几乎可以忽略不计。这种不拘一格的思路确实值得学习一下。