C# 随机填充数组,不重复

C# 随机填充数组,不重复,c#,recursion,repeat,C#,Recursion,Repeat,我试图用1-10的随机数填充一个数组,不重复。我试着用递归来做。我尝试使用递归和不使用递归(这里是两种方法,两种方法都没有运气)。我有两个代码,两个都不起作用: 1: 静态int-reco(int-arr,int[]次) { 随机rnd=新随机(); arr=rnd.Next(1,11); 返回次数[arr]>0?记录(arr,次数):arr; } 静态void Main(字符串[]参数) { int i=0; int[]arr=新的int[10]; int[]次=新int[11]; 随机rnd

我试图用1-10的随机数填充一个数组,不重复。我试着用递归来做。我尝试使用递归和不使用递归(这里是两种方法,两种方法都没有运气)。我有两个代码,两个都不起作用:

1:

静态int-reco(int-arr,int[]次)
{
随机rnd=新随机();
arr=rnd.Next(1,11);
返回次数[arr]>0?记录(arr,次数):arr;
}
静态void Main(字符串[]参数)
{
int i=0;
int[]arr=新的int[10];
int[]次=新int[11];
随机rnd=新随机();
对于(i=0;i<10;i++)
{
arr[i]=rnd.Next(1,11);
次数[arr[i]]++;
如果(乘以[arr[i]]>0)
arr[i]=记录(arr[i],次);
}

2:

静态int-reco(int-arr,int[]次)
{
随机rnd=新随机();
arr=rnd.Next(1,11);
如果(次[arr]>0)
返回记录(arr,次);
其他的
返回arr;
}
静态void Main(字符串[]参数)
{
int i=0;
int[]arr=新的int[10];
int[]次=新int[11];
随机rnd=新随机();
对于(i=0;i<10;i++)
{
arr[i]=rnd.Next(1,11);
如果(乘以[arr[i]]>0)
arr[i]=记录(arr[i],次);
次数[arr[i]]++;
}
}
静态void Main()
{
int[]arr=新的int[10];
列表编号=可枚举的.Range(1,10).ToList();
随机rnd=新随机();
对于(int i=0;i<10;i++)
{
int index=rnd.Next(0,number.Count-1);
arr[i]=数字[索引];
数字。删除(索引);
}
}

如果您只需要1到10之间的随机数,您可以使用
Enumerable.Range
并随机排序

var ran = new Random();
int[] randomArray = Enumerable.Range(1, 10).OrderBy(x => ran.Next()).ToArray();
在特定范围内生成唯一的“随机”数字,如:

List<int> theList = Enumerable.Range(0, 10).ToList();
theList.Shuffle();
洗牌函数(源:):

publicstaticvoidshuffle(此IList列表)
{  
随机rng=新随机();
int n=list.Count;
而(n>1){
n--;
int k=下一个(n+1);
T值=列表[k];
列表[k]=列表[n];
列表[n]=值;
}  
}

您可以这样做。递归版本留作原始海报的练习,因为这个问题听起来像是家庭作业练习:

int[] arr = new int[10];

// Fill the array with values 1 to 10:
for (int i = 0; i < arr.Length; i++)
{
    arr[i] = i + 1;
}

// Switch pairs of values for unbiased uniform random distribution:
Random rnd = new Random();
for (int i = 0; i < arr.Length - 1; i++)
{
    int j = rnd.Next(i, arr.Length);

    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}
int[]arr=newint[10];
//用值1到10填充数组:
对于(int i=0;i
这使用了Eric Lippert在下面的评论中提出的方法。

既然您使用的是C#,并且您知道数组中的随机数,为什么不创建一个数组,然后随机化位置呢?下面是一个示例:

using System.Linq;

//......

Random rand = new Random();
int[] randomNumbers = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
randomNumbers.OrderBy(num => rand.Next());

请详细说明你的分析,它“不起作用”。如果您的意思是用值0..N以随机顺序填充数组0..N,那么标准的方法是首先用值0..N填充数组,然后在数组上迭代,并在数组中的随机位置将每个值与另一个值交换-即随机。guid不是随机性的来源,而是唯一性的来源。guid生成器被允许生成顺序guid。如果您没有使用guid来实现唯一性,则说明您做错了。@EricLippert,对于guid.NewGuid()我会觉得很奇怪要吐出一大堆连续的guid,但我明白你的意思,并更新了我的答案,改为使用Random:)所有这些新的guid可以保证生成的guid是唯一的概率非常高。(有些情况下,即使版本1的guid也不是唯一的。)版本4 GUID是伪随机的,但是不能保证GUID生成器生成版本4 GUID。许多GUID生成器在一天内生成了顺序的1版本GUID。虽然这个解决方案适用于小数组,但是如果尝试使用它来洗牌一百万个元素,会发生什么。运行?@EricLippert-同意,先生!但是大范围的解决方案是什么?Knuth Fischer Yates shuffle。您的交换数量(1)不必要的大,和(2)不产生均匀的分布。考虑使用KunuthStuffle代替。@ EricLippert:我以前从未听说过这个算法。我理解它为什么工作,并相应地改变了代码。到目前为止,这是唯一的解决方案,它都是均匀分布的(到随机产生均匀分布的程度)。而且对于任意大小的列表都很有效。我会通过
Random
的实例。默认的
Random
构造函数被设计破坏了。
List<int> theList = Enumerable.Range(0, 10).ToList();
theList.Shuffle();
[1,5,4,8,2,9,6,3,7,0]
public static void Shuffle<T>(this IList<T> list)  
{  
    Random rng = new Random();  
    int n = list.Count;  
    while (n > 1) {  
        n--;  
        int k = rng.Next(n + 1);  
        T value = list[k];  
        list[k] = list[n];  
        list[n] = value;  
    }  
}
int[] arr = new int[10];

// Fill the array with values 1 to 10:
for (int i = 0; i < arr.Length; i++)
{
    arr[i] = i + 1;
}

// Switch pairs of values for unbiased uniform random distribution:
Random rnd = new Random();
for (int i = 0; i < arr.Length - 1; i++)
{
    int j = rnd.Next(i, arr.Length);

    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}
using System.Linq;

//......

Random rand = new Random();
int[] randomNumbers = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
randomNumbers.OrderBy(num => rand.Next());