C# 为随机和不重复创建编号

C# 为随机和不重复创建编号,c#,random,numbers,C#,Random,Numbers,我是代码: Random rand = new Random(); int[] arr = new int[4]; for (int i = 0; i < 4; i++) { for (int k = 0; k < 4; k++) { int rad = rand.Next(1, 5); if (arr[k] != rad)

我是代码:

       Random rand = new Random();
       int[] arr = new int[4];
       for (int i = 0; i < 4; i++)
       {
           for (int k = 0; k < 4; k++)
           {
               int rad = rand.Next(1, 5);
               if (arr[k] != rad)
                   arr[i] = rad;
           }
       }
       for (int i = 0; i < 4; i++)
           MessageBox.Show(arr[i].ToString());
Random rand=new Random();
int[]arr=新的int[4];
对于(int i=0;i<4;i++)
{
对于(int k=0;k<4;k++)
{
int rad=rand.Next(1,5);
如果(arr[k]!=rad)
arr[i]=rad;
}
}
对于(int i=0;i<4;i++)
Show(arr[i].ToString());
我想要从凌晨1点到4点的生产编号,并且彼此不相等。
tnx.

创建一个包含所需号码的列表,然后将其洗牌:

var rnd = new Random();
List<int> rndList = Enumerable.Range(1, 4).OrderBy(r => rnd.Next()).ToList();

创建一个具有唯一元素的数组,然后对其进行洗牌,如下面的代码所示,它将以使用的统一随机顺序洗牌数组:

int N=20;
var theArray=新整数[N];
对于(int i=0;i
Jon Skeet给出了很好的答案,可以找到算法的解释和模板版本

public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
{
    T[] elements = source.ToArray();
    // Note i > 0 to avoid final pointless iteration
    for (int i = elements.Length-1; i > 0; i--)
    {
        // Swap element "i" with a random earlier element it (or itself)
        int swapIndex = rng.Next(i + 1);
        T tmp = elements[i];
        elements[i] = elements[swapIndex];
        elements[swapIndex] = tmp;
    }
    // Lazily yield (avoiding aliasing issues etc)
    foreach (T element in elements)
    {
        yield return element;
    }
}
公共静态IEnumerable Shuffle(此IEnumerable源,随机rng)
{
T[]元素=source.ToArray();
//注意i>0以避免最终无意义的迭代
对于(int i=elements.Length-1;i>0;i--)
{
//将元素“i”与随机较早的元素it(或其本身)交换
int swapIndex=rng.Next(i+1);
T tmp=元素[i];
元素[i]=元素[swapIndex];
元素[swapIndex]=tmp;
}
//惰性屈服(避免别名问题等)
foreach(元素中的T元素)
{
收益-收益要素;
}
}

反过来想:

而不是:

生成一个数字,然后检查它是否重复

你这样做是为了:

您已经有一组不重复的数字,然后您接受它 一个接一个-消除重复的可能性

这样做可以:

List<int> list = Enumerable.Range(1, 4).ToList();
List<int> rndList = new List<int>();
Random rnd = new Random();
int no = 0;
for (int i = 0; i < 4; ++i) {
    no = rnd.Next(0, list.Count);
    rndList.Add(list[no]);
    list.Remove(list[no]);
}
List List=Enumerable.Range(1,4).ToList();
List rndList=新列表();
随机rnd=新随机();
int no=0;
对于(int i=0;i<4;++i){
否=rnd.Next(0,list.Count);
rndList.Add(列表[编号]);
列表。删除(列表[编号]);
}
结果显示在您的
rndList

这样,就不会发生重复。

int[]arr=newint[5];
int[] arr = new int[5];
int i = 0;
while (i < 5)
{
    Random rand = new Random();
    int a = rand.Next(1,6);

    bool alreadyexist = false;
    for (int j = 0; j < 5; j++)
    {

        if (a == arr[j])
        {
            alreadyexist = true;
        }

    }
    if (alreadyexist == false)
    {
        arr[i] = a;
        i++;
    }

}
for (int k = 0; k < 5; k++)
{

    MessageBox.Show(arr[k].ToString());
}
int i=0; 而(i<5) { Random rand=新的Random(); int a=下一个随机数(1,6); bool-alreadyexist=false; 对于(int j=0;j<5;j++) { 如果(a==arr[j]) { alreadyexist=真; } } if(alreadyexist==false) { arr[i]=a; i++; } } 对于(int k=0;k<5;k++) { Show(arr[k].ToString()); }
创建数组
{1,2,3,4}
并用另一个算法将其洗牌。这是常见的感谢。我不想从列表中使用。我想做正确的阵列。因为我有一个游戏right@user5566530我知道这种方法是有效的,但我总是不喜欢看到当一个O(N)存在时,有人提出O(N Log(N))算法。这个实现是O(N Log N),我给出的是O(N)。此外,此实现不会提供统一的随机顺序。请看这篇文章中的解释,你不应该在每次迭代中随机创建,如果它发生得太频繁,它可能会给出相同的顺序和值。复杂度高于线性,特别是当您过于频繁地创建随机对象时,这种实现更是如此。此外,此实现不会提供统一的随机顺序,至少要使用Fisher-Yates。这个答案不应该被接受。谢谢。但是这个答案和我在我的项目中得到帮助的答案为什么在运行代码
rndList
包含
0,0,3,0
后,您在@user5566530之后将这个问题从回答改为不回答,“同时生成一个数字,然后检查是否有重复,比简单的Fisher-Yates效率要低。”IvanLeonenko纠正道。它应该是
list[no]
,而不是
no
。谢谢你的通知。关于效率,我并没有他们之间真正的轮廓。但是Fisher-Yates算法可能比我的简单算法更快,正如你所说。我的意见是,我提供的算法非常简单明了。
List<int> list = Enumerable.Range(1, 4).ToList();
List<int> rndList = new List<int>();
Random rnd = new Random();
int no = 0;
for (int i = 0; i < 4; ++i) {
    no = rnd.Next(0, list.Count);
    rndList.Add(list[no]);
    list.Remove(list[no]);
}
int[] arr = new int[5];
int i = 0;
while (i < 5)
{
    Random rand = new Random();
    int a = rand.Next(1,6);

    bool alreadyexist = false;
    for (int j = 0; j < 5; j++)
    {

        if (a == arr[j])
        {
            alreadyexist = true;
        }

    }
    if (alreadyexist == false)
    {
        arr[i] = a;
        i++;
    }

}
for (int k = 0; k < 5; k++)
{

    MessageBox.Show(arr[k].ToString());
}