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
}
- 从
nums
数组创建一个 List
。
- 取一个随机索引;
- 复制
the created list
在该索引处的元素到 card1
数组;
- 从列表中删除该元素,这样您就不能再次复制它;
我必须说,尽管这是一个简单的解决方案,但绝不是最 "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:
首先,我不是 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
}
- 从
nums
数组创建一个List
。 - 取一个随机索引;
- 复制
the created list
在该索引处的元素到card1
数组; - 从列表中删除该元素,这样您就不能再次复制它;
我必须说,尽管这是一个简单的解决方案,但绝不是最 "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: