如何从 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
的两个实例之间的时间没有改变,因为计算机速度如此之快,它们将具有相同的种子,因此具有相同的数字序列。这就是index
和index2
具有相同值的原因。只需使用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# 中的两个数组中获取两个随机字符串的主要内容,如果未能解决你的问题,请参考以下文章