【问题标题】:How can I randomly fill an array with 3 different strings?如何用 3 个不同的字符串随机填充数组?
【发布时间】:2017-04-24 15:28:37
【问题描述】:

我知道如何用整数随机填充数组。

但假设我有AppleBananaOrange
我想以随机顺序用这 3 种水果填充一个数组。
我该怎么做?我应该为此使用 Fisher-Yates Shuffle 吗?

我的数组必须这样写:

string[] basket = new string[20];

【问题讨论】:

  • 循环遍历数组的大小并在每次循环迭代中选择一个随机字符串插入?
  • 如果你不关心重复,只需循环并随机选择一个。如果你这样做了,那么之前有很多关于洗牌的问题
  • 我认为 OP 确实关心重复项,因为他提到了 Fisher-Yates shuffle,它通过对集合进行改组来获得集合的排列。
  • 结果必须是真正随机的吗?您可以拥有所有可能结果的List<string>,使用一些简单的LINQ,您可以OrderBy(x => Guid.NewGuid()),然后Take(3).ToArray()
  • 我觉得即使我们说,“是的,使用 Fisher-Yates shuffle 来执行此操作”,那么您仍然会被卡住,因为您的问题似乎是“我如何随机选择一个字符串?@ 987654329@ 处理数字,而不是字符串”——我的意思是,如果这是您的问题,那么请明确表示,不要将自己与 XY Problem 混淆。 @BlakeThingstad 那么为什么他的数组大小为 20? “每 3 个条目使用 Fisher-Yates 洗牌,然后重新开始并继续这样做,直到数组被填满”我想这是有道理的。

标签: c# arrays


【解决方案1】:

如果将所有字符串添加到列表中,则可以循环并随机选择一个值并将其添加到数组中

List<string> list = new List<string>();

list.Add("Apple");
list.Add("Banana");
list.Add("Orange");

string[] basket = new string[20];

Random rd = new Random();

for(int i = 0; i < basket.Length; i++)
{
    int randomValue = rd.Next(list.Count);

    basket[i] = list[randomValue];
}

【讨论】:

  • 所有答案在这个主题上可能都很好,但我觉得在这个主题中,我实际上可以理解在我受教育的这一点上发生了什么。因此,我将此标记为已接受。谢谢!
【解决方案2】:

所以,我现在在学校,所以我不能自己测试代码,但如果我是对的,代码可能会变成这样。

int Strings = 3;
string[] a1 = new[] {
  "Apple",
  "Banana",
  "Orange",
}

Random r1 = new Random();

string b1 = a1[r1.Next(0, a1.Length)];
listBox1.Items.Add(b1);

string b2 = a1[r1.Next(0, a1.Length)];
if (listBox1.Items.Contains(b2))
{
  b2 = a1[r1.Next(0, a1.Length)];
  listBox1.Items.Add(b2);
}
else
{
  listBox1.Items.Add(b2);
}
string b3 = a1[r1.Next(0, a1.Length)];
if (listBox1.Items.Contains(b3))
{
  b3 = a1[r1.Next(0, a1.Length)];
  listBox1.Items.Add(b3);
}
else
{
  listBox1.Items.Add(b3);
}

这里还有一个可以帮助您的 C# 类。 https://msdn.microsoft.com/en-us/library/system.random(v=vs.110).aspx

它还检查字符串是否在列表框中并重新路由它,所以它会得到一个不同的字符串,你会想要进行检查,当它碰巧是相同的字符串时继续它。

【讨论】:

  • 忘记删除 int 字符串,我正在测试另一种方法。
【解决方案3】:

创建一个所需大小的IEnumerable,然后为每个项目从您的字符串数组中选择一个随机索引

var desiredArrayLength = 20; // Should be const or from config

var strings = new[] { "Apple", "Banana", "Orange" };
Random random = new Random();

var basket = Enumerable.Range(1, desiredArrayLength)
                       .Select(i => strings[random.Next(strings.Length)]).ToArray();

确保无论您决定如何初始化 basket,都不要执行类似 new string[20] 的操作 - 使用 const/config 值,这样它就不会是幻数

更多关于幻数的信息:What is a magic number, and why is it bad?

【讨论】:

  • 为什么我不能使用你所说的幻数?这就是他们在学校教我们的方式。这个作业的例子就是这样做的,新字符串[20] :(
  • @Tenakey - 请参阅添加到答案的链接 :) 如果他们希望您使用幻数来获得它,那么您可以为作业做它 - 但要知道什么是好的模式:)
【解决方案4】:

构建一个扩展来重复和洗牌任何集合(这个使用Fisher-Yates)

public static class EnumerableExtensions
{
    private static readonly Random _rng = new Random();

    public static IEnumerable<T> Shuffle<T>( this IEnumerable<T> collection, Random rng = null )
    {
        rng = rng ?? _rng;

        var list = collection.ToList();
        for (int i = 0; i < list.Count; i++)
        {
            var j = i + rng.Next( list.Count - i );
            yield return list[j];
            if (i != j)
            {
                list[j] = list[i];
            }
        }
    }

    public static IEnumerable<T> Repeat<T>(this IEnumerable<T> collection, int count)
    {
        for ( int i = 0; i < count; i++ )
        {
            foreach ( var item in collection )
            {
                yield return item;
            }
        }
    }

}

并像使用它

string[] fruits = new string[] { "Apple", "Banana", "Orange" };
string[] basket = fruits
    .Repeat( ( 20 + fruits.Length - 1 ) / fruits.Length )
    .Shuffle()
    .Take( 20 )
    .ToArray();

更多随机可以通过

public static class EnumerableExtensions
{
    ...

    public static IEnumerable<T> RandomRepeat<T>(this IEnumerable<T> collection, int count, Random rng = null)
    {
        rng = rng ?? _rng;
        var list = collection.ToList();
        for ( int i = 0; i < count; i++ )
        {
            var j = rng.Next( list.Count );
            yield return list[j];
        }
    }
}

string[] fruits = new string[] { "Apple", "Banana", "Orange" };
string[] basket = fruits.RandomRepeat( 20 ).ToArray();

【讨论】:

  • 改组很好,但他将如何随机填充数组以开始(这是问题):)
  • @GiladGreen 订购的填充,随机播放和返回,或随机填充有什么区别?两者都有随机顺序
  • 随机填充不同于填充然后随机排序。如果用 3 个不同的值填充大小为 20 的数组,那么您希望每个值有多少个?如果您不随机填写,那么您实际上已经决定了每个项目将拥有多少
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-01
相关资源
最近更新 更多