【问题标题】:How can I make random numbers that never repeat in array?如何制作永远不会在数组中重复的随机数?
【发布时间】:2013-11-30 19:28:25
【问题描述】:
listBox1.Items.Clear();
int[] sayısal = new int[6];
Random rastgele = new Random();
for (int i = 0; i < 6; i++)
{
   do
   {
      sayısal = rastgele.Next(1, 50);
   }
   while (listBox1.Items.IndexOf(sayısal) != -1);
      listBox1.Items.Add(sayısal);
}

当我这样做时,我会遇到一个错误,调用

"不能将类型'int'隐式转换为'int[]'"

在线"sayısal = rastgele.Next(1, 50);"。我能为它做些什么?

【问题讨论】:

  • 欢迎来到 Stackoverflow。下次格式化时请多加注意。

标签: c# arrays random


【解决方案1】:

您可以生成序列1..50 并将其打乱(即按随机值排序):

Random rastgele = new Random();
int[] sayısal = Enumerable.Range(1, 50) // generate sequence
                          .OrderBy(i => rastgele.Next()) // shuffle
                          .Take(6) // if you need only 6 numbers
                          .ToArray(); // convert to array

您的代码不起作用,因为您试图将生成的项目分配给数组变量。

sayısal = rastgele.Next(1, 50);

应该是:

do {
   sayısal[i] = rastgele.Next(1, 50);
} while(listBox1.Items.IndexOf(sayısal[i]) != -1);

正如我在 cmets 中已经指出的,最好将 UI 逻辑和数组生成分开。即

// generate array (optionally move to separate method)
int itemsCount = 6;
int[] items = new int[itemsCount]; // consider to use List<int>
Random random = new Random();
int item;

for(int i = 0; i < itemsCount; i++)
{
   do {
      item = random.Next(1, 50);
   } while(Array.IndexOf(items, item) >= 0);

   items[i] = item;
}

// display generated items
listBox1.Items.Clear();
for(int i = 0; i < items.Length; i++) // or use foreach
    listBox1.Items.Add(items[i]);

【讨论】:

  • 我明白你的意思,但“Array.IndexOf(item)”和“listBox1.Items.AddRange(items);”中也有错误。我很高兴你的帮助。我不擅长 C#,我无法理解这些错误。
  • 当我这样做时,我可以插入随机数,但它可以重复相同的数字。 private void button1_Click(object sender, EventArgs e) { listBox1.Items.Clear(); int[] sayi = new int[6];随机 rnd = new Random(); for (int i = 0; i
  • @user3052898 抱歉,更新代码(我发的时候没用VS,所以泄露了一些编译器错误)
【解决方案2】:

因为Random.Next 方法返回int,而不是int[]。从int[]int 并没有隐含的对话。

Return Value
Type: System.Int32
A 32-bit signed integer greater than or equal to minValue and less than maxValue; that is, the range of return values includes minValue but not maxValue. If minValue equals maxValue, minValue is returned.

如果你想填充你的数组,你可以使用Enumerable.Range like lazyberezovsky mentioned

【讨论】:

  • 也是正确答案:)我也认为在列表框中获取数组的索引也不是很好的主意:)
  • 我现在正在学习 C#,我们的老师希望我们能成功。我几乎到处搜索,但找不到任何东西。
  • @user3052898 我建议您将数组生成和在 UI 上显示项目分开。 IE。在不引用列表框的情况下生成数组
  • @user3052898 看看lazyberezovsky's answer 然后呢?
  • @lazyberezovsky 他可能会得到一个 BrainOverflow :)
【解决方案3】:

此方法采用整数数组并随机排序。 因此,用循环填充数组,然后使用它对数组进行随机排序。 您应该相信其中一个人,因为他们是第一个发布有效答案的人。我只是认为另一种方法会很好。

amount 是您希望数组随机化的次数。数字越大,数字随机的机会就越高。

    private Random random = new Random();

    private int[] randomizeArray(int[] i, int amount)
    {
        int L = i.Length - 1;
        int c = 0;
        int r = random.Next(amount);
        int prev = 0;
        int current = 0;
        int temp;

        while (c < r)
        {
            current = random.Next(0, L);
            if (current != prev)
            {
                temp = i[prev];
                i[prev] = i[current];
                i[current] = temp;
                c++;
            }
        }
        return i;
    }

【讨论】:

    【解决方案4】:

    在选择数据结构和算法时要小心,如果选错了,最终会得到 O(n^2)。恕我直言,一个合理的解决方案是一个类型化的哈希表(即字典),它会给你 O(n):

    Random rnd = new Random();              
            var numbers = Enumerable
                .Range(1, 1000000)
                .Aggregate(new Dictionary<int, int>(), (a, b) => {
                    int val;
                    do {val = rnd.Next();} while (a.ContainsKey(val));
                    a.Add(val, val);
                    return a;
                })
                .Values
                .ToArray();
    

    仍然不理想,因为性能取决于数组大小明显小于可用数字集,并且无法检测何时不满足此条件(或更糟糕的是,当它更大时,在这种情况下算法将进入无限循环)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-24
      • 1970-01-01
      • 2012-10-22
      • 1970-01-01
      • 2021-09-28
      • 1970-01-01
      • 2012-10-23
      相关资源
      最近更新 更多