如何从 C# 中的两个数组中获取两个随机字符串

Posted

技术标签:

【中文标题】如何从 C# 中的两个数组中获取两个随机字符串【英文标题】:How can I get two random strings from two arrays in C# 【发布时间】:2020-12-04 08:36:13 【问题描述】:

如何从两个数组中随机获取两个字符串。我有东西,但它不是随机选择的。

string[] firstNames =  "John", "Michael", "Victor", "Mark", "Alex", "Steven", "Zack", "Howard", "Xzavier", "Brendan", "Dustin", "Carl" ;
string[] lastNames =  "Adams", "McGregor", "Piasta", "Semmel", "Laris", "Sever", "Bourque", "Percy", "Shanabarger", "Bobak", "Adair" ;
string[] shuffled = firstNames.OrderBy(n => Guid.NewGuid()).ToArray();
string[] shuffled2 = firstNames.OrderBy(n => Guid.NewGuid()).ToArray();
Random firstn = new Random();
Random lastn = new Random();
int index = firstn.Next(firstNames.Length);
int index2 = lastn.Next(lastNames.Length);
Console.WriteLine($"The random name is firstNames[index]" + $" lastNames[index2]");

我正在尝试制作一个随机的全名生成器。我已多次尝试此代码,结果是:John Adams、Victor Piasta 等等!您可以看到它们不是随机的。

【问题讨论】:

尝试为您的两个索引使用相同的 Random 实例。 我该怎么做? int index2 = firstn.Next(lastNames.Length); @TimRutter 为该问题添加一个答案,以便我将您的答案标记为最佳。 【参考方案1】:

对我来说看起来很随意..

通过 150 次迭代,您仍然可以获得 132 种可能组合中大约 90 种的性能。

测试代码:

HashSet<string> names = new HashSet<string>(150);

Random rndm = new Random();

for (int i = 0; i < 150; i++)

    names.Add($"firstNames[rndm.Next(firstNames.Length)] " +
              $"lastNames[rndm.Next(lastNames.Length)]");


Console.WriteLine($"names.Count / firstNames.Length * lastNames.Length");
Console.ReadKey();

不要忘记,真正的随机是不可能模拟的……所以你总是会有某种具有更高数字的重复分布。

【讨论】:

【参考方案2】:

.NET-Framework 与 .NET-Core 中的随机工作方式略有不同

在 .NET Framework 中,默认种子值取决于时间。在 .NET Core 中,默认种子值由线程静态伪随机数生成器生成。

发件人:https://docs.microsoft.com/en-us/dotnet/api/system.random?view=netcore-3.1#Instantiate

仅在 .NET-Framework 中,在大多数 Windows 系统上,在 15 毫秒内创建的随机对象可能具有相同的种子值。

在 .NET-Framework 上使用单个随机实例来避免这种行为。

【讨论】:

这真的回答了 OP 的问题吗? 是的,因为 OP 的问题是由于 .net Core 中的默认种子错误 好吧,在我的 .NET Core 3.1 机器上,一个或两个 Random 实例之间绝对没有区别……尽管我同意创建一个更有意义。查看我提供的示例,它使用 2 个不同的实例产生相同的结果。 .Net 框架:dotnetfiddle.net/WRo34y - .Net 核心:dotnetfiddle.net/iCWm4D 这个答案解释了.Net Framework / .Net Core 之间的区别。【参考方案3】:

只需更改为下面,以便您对两者使用相同的 Random 实例

int index2 = firstn.Next(lastNames.Length);

【讨论】:

【参考方案4】:

Random 实际上并不生成随机数,而是伪随机数。这意味着,您需要一个起始值,即所谓的种子。从该值计算第一个数字。由此,人们可以计算出另一个数字,依此类推。这些数字看起来像是随机的,但实际上它们是由种子决定的。如果你有相同的种子,你总是得到相同的数字序列。

您的Random 类实际上有一个构造函数,您可以在其中传递种子。你可以在这里试试:https://dotnetfiddle.net/0bHDNg 对于同一个种子,你总是会得到相同的数字序列。

如果使用不带参数的构造函数,则以当前时间为种子。这有一个很大的优势,当您重新启动程序时,您总是会得到不同的数字序列。但是在您的示例中,您有一个问题:如果创建 Random 的两个实例之间的时间没有改变,因为计算机速度如此之快,它们将具有相同的种子,因此具有相同的数字序列。这就是indexindex2 具有相同值的原因。只需使用Random 的相同实例来生成两个索引,它们不一定具有相同的值:

Random random = new Random();
int index = random .Next(firstNames.Length);
int index2 = random .Next(lastNames.Length);
Console.WriteLine($"The random name is firstNames[index]" + $" lastNames[index2]");

【讨论】:

以上是关于如何从 C# 中的两个数组中获取两个随机字符串的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中获取两个字符串数组之间的差异?

如何生成保存到数组中的随机字符串? c# [重复]

如何在 C# 数组字符串中选择 5 位随机数? [复制]

C#:如何查找两个字符串数组是不是包含相同的值

从Firestore获取一个ArrayList并从该列表中选择3个随机字符串

如何随机从数组中获取随机字符串项,并将字符串单词的每个字符随机放入li标签中