C# 如何创建随机整数[]

C# 如何创建随机整数[],c#,arrays,random,C#,Arrays,Random,我需要创建一个带有特定参数的int随机数组 int[] test = new int[80]; Random random = new Random(); 我需要将1和0随机分配给数组。我知道怎么做 test[position] = Random.Next(0,2);//obviously with a for loop 但我需要精确的20个1,但它们需要在数组中随机定位。我不知道如何确保1是随机定位的,并且正好有20个1。数组中的其余位置将分配为0。您可以这样做 for (int i =

我需要创建一个带有特定参数的int随机数组

int[] test = new int[80];
Random random = new Random();
我需要将1和0随机分配给数组。我知道怎么做

test[position] = Random.Next(0,2);//obviously with a for loop
但我需要精确的20个1,但它们需要在数组中随机定位。我不知道如何确保1是随机定位的,并且正好有20个1。数组中的其余位置将分配为0。

您可以这样做

for (int i = 0; i < 20; i++)
{
    var rand = random.Next(0,80);
    if (test[rand] == 1)
    {
        i--;
        continue;
    }
    test[rand] = 1;
}
for(int i=0;i<20;i++)
{
var rand=随机。下一个(0,80);
如果(测试[rand]==1)
{
我--;
持续
}
试验[rand]=1;
}

剩余值自动为零。

如果您知道您需要一个值中的20,那么更好的方法是使用所需值预先填充数组,然后将其洗牌

像这样的方法应该会奏效:

int[] array = new int[80];
for (int i = 0; i < 80; i++)
{
    int val = 0;
    if (i < 20)
    {
        val = 1;
    }
    array[i] = val;            
}

Random rnd = new Random();
int[] shuffledArray = array.OrderBy(x => rnd.Next()).ToArray();
int[]数组=新的int[80];
对于(int i=0;i<80;i++)
{
int-val=0;
如果(i<20)
{
val=1;
}
数组[i]=val;
}
随机rnd=新随机();
int[]shuffledArray=array.OrderBy(x=>rnd.Next()).ToArray();

我认为你需要改变你的想法

考虑:

var cnt = 20;
while (cnt > 0) {
    var r = Random.Next(0, 80);
    if (test[r] != 1) {
        test[r] = 1;
        cnt--;
    }
}
根据CodeCaster的评论展开解释。这段代码不是生成要放入数组的随机值,而是生成和设置索引。由于C#会自动将测试数组初始化为0,因此这些值已经设置好了。所以你只需要加上你的1值。代码生成一个随机索引,测试它是否为1,如果为1,则设置数组元素并递减计数(cnt)。一旦计数达到零,循环终止

如果需要的值超过0和1,则此函数将无法正常工作。当然,这些问题明确指出,这些是所需的价值观


“这会导致糟糕的运行时性能”。什么你能证明这一点吗?生成的索引有可能与现有条目冲突。此几率随着1的增加而增加。最坏的情况是有19/80(~23%)的碰撞概率

如果random两次返回同一个索引,这将不起作用。@OldProgrammer:已修复。这只是一个太幼稚的实现,不必要地运行了大量循环,设置为0也是不必要的。不,它不会只循环20次。的确,它最多将20个索引设置为1,但理论上,如果只生成19个不同的索引,那么该代码将循环无限次。这种“循环并生成随机索引”的方法对于这个问题来说是完全错误的方法,所有答案都是同样错误的。但是通过Fisher-Yates对列表进行洗牌有一个确定的结束状态,并且在
O(N)
的时间内运行。仅仅因为某些东西看起来是随机的并不意味着它是正确的方法。因此,您不希望数组中填充随机数据,而是希望预定义数组(
var arr=new int[]{1,1,…(20倍),0,0,…(其余)};
)随机洗牌。那是另一回事。尝试对循环进行几次迭代,然后随机交换两个元素。生成一个包含20个1和N-20个0的列表,然后将其洗牌。使用Random也可以生成一个随机索引。您首先必须检查该插槽是否已分配,然后继续调用random(0,80),直到获得未使用的插槽。不要按random.Next()排序。使用适当的洗牌算法。好的,谢谢你添加了这个非常详细的解释。这样,人们会被警告这是次优代码,这取决于他们是否将其复制粘贴到程序中。由于潜在的冲突,性能是次优的,并且不是完全随机的。适当的洗牌是最佳解决方案。