使用.NET随机化字符串数组的最佳方法是什么?我的数组包含大约500个字符串,我想创建一个新的Array
,其中包含相同的字符串,但顺序是随机的。
请在您的答案中包含一个C#示例。
发布于 2008-09-20 17:40:06
如果你使用的是.NET 3.5,你可以使用下面的IEnumerable coolness:
Random rnd=new Random();
string[] MyRandomArray = MyArray.OrderBy(x => rnd.Next()).ToArray();
编辑:下面是相应的VB.NET代码:
Dim rnd As New System.Random
Dim MyRandomArray = MyArray.OrderBy(Function() rnd.Next()).ToArray()
第二,为了回应System.Random“不是线程安全的”和“只适用于玩具应用程序”的评论,因为它返回了基于时间的序列:正如我在示例中所使用的,Random()是完全线程安全的,除非您允许重新输入将数组随机化的例程,在这种情况下,您无论如何都需要像lock (MyRandomArray)
这样的东西,这样才不会损坏您的数据,这也将保护rnd
。
此外,应该很好地理解,System.Random作为熵的来源并不是很强。正如MSDN documentation中所指出的,如果您正在做任何与安全相关的事情,那么您应该使用从System.Security.Cryptography.RandomNumberGenerator
派生的内容。例如:
using System.Security.Cryptography;
..。
RNGCryptoServiceProvider rnd = new RNGCryptoServiceProvider();
string[] MyRandomArray = MyArray.OrderBy(x => GetNextInt32(rnd)).ToArray();
..。
static int GetNextInt32(RNGCryptoServiceProvider rnd)
{
byte[] randomInt = new byte[4];
rnd.GetBytes(randomInt);
return Convert.ToInt32(randomInt[0]);
}
发布于 2008-09-21 08:51:47
下面的实现使用Fisher-Yates algorithm,也就是Knuth Shuffle。它在O(n)时间内运行,并就地洗牌,因此比“按随机排序”技术性能更好,尽管它的代码行更多。有关性能测量的一些比较信息,请参阅here。我已经使用过System.Random,这对于非加密目的来说很好。*
static class RandomExtensions
{
public static void Shuffle<T> (this Random rng, T[] array)
{
int n = array.Length;
while (n > 1)
{
int k = rng.Next(n--);
T temp = array[n];
array[n] = array[k];
array[k] = temp;
}
}
}
用法:
var array = new int[] {1, 2, 3, 4};
var rng = new Random();
rng.Shuffle(array);
rng.Shuffle(array); // different order from first call to Shuffle
*对于更长的数组,为了使(极大的)排列数量相等,有必要对每个交换运行伪随机数生成器(PRNG)多次迭代,以产生足够的熵。对于500个元素的数组,只有500个元素的一小部分!使用PRNG可以获得排列。尽管如此,Fisher-Yates算法是没有偏见的,因此混洗效果将与您使用的RNG一样好。
发布于 2010-08-18 23:45:00
您还可以在Matt Howells之外创建一个扩展方法。举例说明。
namespace System
{
public static class MSSystemExtenstions
{
private static Random rng = new Random();
public static void Shuffle<T>(this T[] array)
{
rng = new Random();
int n = array.Length;
while (n > 1)
{
int k = rng.Next(n);
n--;
T temp = array[n];
array[n] = array[k];
array[k] = temp;
}
}
}
}
然后你可以像这样使用它:
string[] names = new string[] {
"Aaron Moline1",
"Aaron Moline2",
"Aaron Moline3",
"Aaron Moline4",
"Aaron Moline5",
"Aaron Moline6",
"Aaron Moline7",
"Aaron Moline8",
"Aaron Moline9",
};
names.Shuffle<string>();
https://stackoverflow.com/questions/108819
复制相似问题