问题 如何在随机位置填充具有1和0的特定数字的数组?


我有一个阵列有8个点填充,4个1和4个零填充它,但希望位置是随机的。我有点难以理解如何做到这一点,而不是多余。有没有一种简单的方法可以做到这一点,或者我必须随机填充1或0的数组然后检查,看看它是否具有正确数量的两者?我目前的代码是沿着的

void setup() {
  int one = 0;
  randomSeed(analogRead(A0));
  for (int i=0; i<8; i++){
    array[i] = random(0, 2);
    if (array[i] == 1){
      one++;
    }
    if(one >4){
      array[i] = 0;
      one--;
    }
  }
}

这大部分都有效,但有一些明显的缺点,所以任何关于更好的方法的指针都会受到赞赏。


10745
2017-10-23 18:05


起源

我可能会将数组设置为[1,1,1,1,0,0,0,0],然后将其洗牌。随机选择两个元素并多次交换它们。 - Octopus
这不是一个坏主意,我必须考虑到这一点,它绝对是一个不错的选择。 - Christian Remwood Wikitiki33
@Octopus的建议可以 为你执行 std::shuffle。 - user4581301


答案:


更新:此答案与原始答案略有不同

对于资源紧张的Arduino,此代码就足够了,无需链接额外的库:

int a[8] = { 0,0,0,0,1,1,1,1 };


void setup() {

  randomSeed(analogRead(A0));

  for (int n=7;n>0;n--) {
    int r = random(n+1);
    int t = a[n];
    a[n] = a[r];
    a[r] = t;
  }

}

这正是std :: shuffle函数的实现方式,仅限于内置Arduino的有效性 random() 功能


5
2017-10-23 18:40



这看起来是个不错的选择 - Christian Remwood Wikitiki33
shuffle的这种“天真”实现不会以相同的概率产生排列。 OP并未声明他们希望针对不同的排列进行均匀分布,但这通常是隐含的。如果是这样,这个解决方案甚至都不可接受。 - AnT
AnT是对的。这是一个非常好的主意,但实施存在缺陷。使用 std::shuffle我认为即使在Arduino上也应该可用。 - Adrian McCarthy
@Adrian,即使互换数量增加了?我想看看这个证据。 - Octopus
@Octopus:我相信本节的第二段涵盖了它。 en.wikipedia.org/wiki/... - Adrian McCarthy


如果你需要生成 m 在零数组中的随机数,您可以简单地遍历整个数组并将当前元素设置为1,具有以下概率 P

           number of 1's that remains to be set
P = ----------------------------------------------------
    number of array elements that remains to be iterated

在你的情况下,你需要在8个元素的数组中设置4个随机1

const unsigned N = 8, M = 4;
int array[N];

for (unsigned i = 0, m = M; i < N; ++i)
  if (rand() % (N - i) < m)
  {
    array[i] = 1;
    --m;
  }
  else
    array[i] = 0;

这会在一次传递中生成随机数组 - 无需后续随机播放任何内容。

附:为了用上述概率做出决定 P 我使用了经常被批评的人 rand() % (N - i) < m 方法。当然,这是重点。您可以使用您选择的任何其他方法。


4
2017-10-23 18:43



我怀疑这对Arduino有用。 - gre_gor