【问题标题】:Shuffle an array of int in C with - without while loop使用 - 不使用 while 循环在 C 中随机播放一个 int 数组
【发布时间】:2018-01-04 16:10:58
【问题描述】:

我想随机播放一个整数数组,该数组已排序,其大小为 n,值为 1 - n。 我只是想避免使用 while 循环以确保 rand() 不会给我相同的索引。 代码看起来像这样:

void shuffleArr(int* arr, size_t n)
{
  int newIndx = 0;
  int i = 0;

  for(; i < n - 1; ++i)
  {
    while((newIndx = i + rand() % (n - i)) == i);

    swap(i, newIndx, arr);
  }
}

for 循环一直持续到 n-1,因此例如在最后一次运行中,它有 50/50 的机会等于 i。我想避免这种想法。

【问题讨论】:

    标签: c loops random while-loop shuffle


    【解决方案1】:

    如果您正在搜索 1...n 范围内的随机数,但不包括该范围内的某个数字 m,则您可以改为获取 1...(n-1) 范围内的随机数以及任何结果 > = m 将值加 1。

    如果您正在寻找对有限列表洗牌算法的解释,请在此处查看 Fisher-Yates:https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle

    【讨论】:

    • Tnx 优先。但是,对于 Fisher-Yates,我仍然不检查我随机分配的数字是否等于索引。
    • 对,除非我弄错了,否则在 Fisher-Yates 中,您会依次检查每个项目并决定一个新的随机位置,不包括已经决定的位置。但是,新的洗牌位置有可能与其当前位置相同,这似乎是有效的。
    • 正是我的观点。这就是为什么我想要 while 循环,以避免这种情况。但是,在最后一次运行时,正如我所说的那样,它将是 50 50 的机会,假设即使那样它也可能是无限循环。
    • 我不确定我们是否在同一页面上 - 您是否同意将元素随机播放到其当前位置是有效的,或者您是否试图消除它?如果您想消除它并以这种方式偏向随机播放,那么我的答案第一段中的方法有问题吗?
    • 现在知道了。我相信我没有安静地理解你的第一个答案。是的,我确实想消除这种情况,并在每次检查 if(res = rand() % (n - 1) >= i) then ++res.你是对的。
    【解决方案2】:

    这是解决方案,它涉及到两者的一点点。

    void Shuffle(int[] arr, size_t n)
    {
      int newIndx = 0;
      int i = 0;
    
      for(; i < n - 2; ++i)
      {
        newIndx = i + rand() % (n - i);
        if(newIndx == i)
        {
          ++newIndx;
        }
    
        swap(i, newIndx, arr);
      }
    }
    

    在有一个好的(随机数!= i)之前不需要循环,因为它是用 if + newIndx 的增量固定的。

    【讨论】:

      猜你喜欢
      • 2016-12-29
      • 2016-06-11
      • 1970-01-01
      • 1970-01-01
      • 2018-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多