【问题标题】:How can I get two random strings from two arrays in C#如何从 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 为该问题添加一个答案,以便我将您的答案标记为最佳。

标签: c# arrays string random


【解决方案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]}");
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-06
        • 2012-06-15
        • 1970-01-01
        相关资源
        最近更新 更多