C#将不同的数组元素随机指定给另一个数组

C# appointing distinct array elements randomly to another array

首先,我不是 C# 专家,所以我希望得到简化的答案。提前致谢..

我有一个包含 30 个元素的数组,所有元素都是整数且彼此不同。我想制作另一个长度为 6 的数组。并将长度为 30 的元素指定到此处,但我不希望数字出现超过一个。 我尝试了随机函数,这显然可以在那里出现相同的数字。我也许可以添加语句,但我认为必须有一条捷径。

想请教各位大佬有没有,如果有请分享一下,再次感谢

int [] nums  = new int[30];
for (int i = 0; i < nums.Length; i++)
{
    nums[i] = i + 1;
}

Random rnd = new Random();
int[] card1 = new int[6];
for (int i = 0; i < card1.Length; i++)
{
    card1[i] = nums[rnd.Next(0, 30)];
}

还有其他方法可以解决这个问题,但既然你要求简化一些,我会尽量不更改你的代码。

Random rnd = new Random();
var values = new List<int>(nums); // 1

int[] card1 = new int[6];
for (int i = 0; i < card1.Length; i++)
{
    var rand = rnd.Next(0, values.Count); // 2
    card1[i] = values[rand]; // 3
    values.RemoveAt(rand); // 4
}
  1. nums 数组创建一个 List
  2. 取一个随机索引;
  3. 复制 the created list 在该索引处的元素到 card1 数组;
  4. 从列表中删除该元素,这样您就不能再次复制它;

我必须说,尽管这是一个简单的解决方案,但绝不是最 "performant" 的解决方案。

所以你的问题,自由翻译是:

I have a sequential, numeric array containing values from 1 through 30. I want to select 6 unique values from this array from random positions.

公认的解决方案是适当地(例如 Fisher-Yates)打乱数组并简单地从前面获取所需元素的数量。

鉴于您可能希望保持原始数组有序,您可以创建一个副本并将其打乱。

看起来像这样:

var sourceArray = // your loop, or something like Enumerable.Range(1, 30).ToArray();
var arrayToPickFrom = Shuffle(sourceArray.ToArray()); // make a copy and shuffle it
var randomCards = arrayToPickFrom.Take(6); // take the first six elements 

或者,问题可以简化:

I want to generate N random, unique numbers between 1 and M.

代码行数更少。但这完全取决于您的要求。如果你真的想创建一个纸牌游戏,在最初的六张牌之后会抽出更多的牌——而且一张牌只能抽一次,你应该完全不同地解决这个问题,对于初学者来说,引入一个牌组 class 包含所有卡片,有方便的方法...

你为什么不拿前6个?

var theOtherArray = Nums.Take(6).ToArray(); 

一个简单的解决方案:

int[] card1 = nums.OrderBy(it => Guid.NewGuid()).Take(6).ToArray();

通过新的 guid 对原始数组进行排序应该会给您一个不错的随机性近似值,同时避免明确防止重复的要求。

那么你只取前6个结果。

警告:按 guid 排序的类似随机行为是当前 Guid.NewGuid() 方法的一个实现细节,因此不要依赖此功能很重要- 特别是在生产代码中。

更好的实现方式是使用 Fisher-Yates 洗牌,例如,请参见 post: