使用c#从数组中随机选择4个元素

本文关键字:选择 4个 元素 随机 数组 使用 | 更新日期: 2023-09-27 18:14:59

我试图在c#中使用随机函数从数组addetailsID中随机选择四个,其中有超过六个元素。

我把这些随机选择到另一个数组strAdDetailsID:

 string[] strAdDetailsID = new string[4];
 for (int i = 0; i < 4; i++)
 {
     Random random = new Random();
     int index = random.Next(0, addetailsID.Length);
     value = addetailsID[index].ToString();
     strAdDetailsID[i] = value;
 }

有时,我从六个元素中得到两个相同的值。我如何让所有四个唯一的值都被选中?

使用c#从数组中随机选择4个元素

您最好对数组进行洗牌,然后选择前4个元素

您可以使用此方法在LINQ中完成此操作。

List<string> list = new List<string>() { "There", "Are", "Many", "Elements", "To", "Arrays" };
foreach (var item in list.OrderBy(f => Guid.NewGuid()).Distinct().Take(4))
{
    Console.WriteLine(item);
}

你的Random random ...位置有问题,但我认为你的攻击方式是错误的。

这可以通过随机排序源并取前4项来解决。

var result = addetails.OrderBy(x => Guid.NewGuid()).Take(4).ToArray();

假设addetails的内容是唯一的(如您所暗示的),您将始终在这里获得4个唯一值。正确使用random,仍然有可能得到重复(因为它是random)。

您需要首先生成4个唯一的索引,然后从源数组中提取随机值:

        string[] addetailsID = new string[20];  // this is the array I want to index into
        // generate the 4 unique indices into addetailsID
        Random random = new Random();
        List<int> indices = new List<int>();
        while (indices.Count < 4)
        {
            int index = random.Next(0, addetailsID.Length);
            if (indices.Count == 0 || !indices.Contains(index))
            {
                indices.Add(index);
            }
        }
        // now get the 4 random values of interest
        string[] strAdDetailsID = new string[4];
        for (int i = 0; i < indices.Count; i++)
        {
            int randomIndex = indices[i];
            strAdDetailsID[i] = addetailsID[randomIndex];
        }

将它们放到列表中,一旦被选中,就从列表中删除。

下面的算法工作得很好,并且不需要额外的存储空间或预洗牌。它确实改变了源数组的顺序,所以如果这是不可行的,那么预洗牌方法是最好的。

在伪代码:

result = []
For i = 0 to numItemsRequired:
    randomIndex = random number between i and source.length - 1
    result.add(source[randomIndex])
    swap(source[randomIndex], source[i])
在c#:

string[] strAdDetailsID = new string[4];
Random rand = new Random();
for (int i = 0; i < 4; i++)
{
    int randIndex = rand.Next(i, adDetailsID.Length);
    strAddDetails[i] = adDetailsID[randIndex];
    string temp = adDetailsID[randIndex];
    adDetailsID[randIndex] = adDetailsID[i];
    adDetails[i] = temp;
}

使用一个列表,删除所有已经使用的项目:

 List<string> addetailsID = new List<string>{"1","2","3","4","5","6"};
 string[] strAdDetailsID = new string[4];
 Random random = new Random();
 for (int i = 0; i < 4; i++)
 {
     int index = random.Next(0, addetailsID.Count);
     string value = addetailsID[index].ToString();
     addetailsID.RemoveAt(index);
     strAdDetailsID[i] = value;
 }
  strAdDetailsID.Dump();

嗯,你应该一个一个地随机选择项目,而不是在选择下一个项目时考虑已经选择的项目。这肯定比洗牌快。

如果源列表很小,您可以复制并从中删除所选项目。否则,像这样:

(让n为数组中的项数)

  1. 设S为所选指标的集合;S =开头空
  2. 从0到n-1-size(S)中选择一个随机索引i
  3. 对于S中每个小于i的索引(从最小索引开始!),在i
  4. 中添加一个
  5. 现在i是一个选择的索引,添加到S
  6. 返回步骤2,直到集合包含4个元素。