`int j = i + rand()/(RAND_MAX /(curr_pos-i)+ 1);`是什么意思?

时间:2020-10-18 17:23:10

标签: c

以下代码是什么意思?什么是RAND_MAX?由于某种原因,我发现这段代码很难理解。我不了解的部分是int j = i + rand()/(RAND_MAX /(curr_pos-i) + 1);

if (curr_pos > 1) {
  for (int i = 0; i < curr_pos-1; i++) {
    int j = i + rand()/(RAND_MAX /(curr_pos-i) + 1);
    swap(&array[j], &array[i]);
  }
}

2 个答案:

答案 0 :(得分:2)

RAND_MAX是在stdlib.h中定义的宏:

兰德返回的最大值

我们将rand()除以RAND_MAX,以获得整数除

所以我们有:

int j = i + rand()/(RAND_MAX /(curr_pos-i) + 1);

表示将j的值分配给i,再加上:

rand()/(RAND_MAX /(curr_pos-i) + 1)

这意味着:将rand()除以:

RAND_MAX /(curr_pos-i) + 1

在这里,curr_pos-i首先被求值,然后我们将RAND_MAX除以它的减法结果。然后,我们将1添加到划分结果中。


PS:尽管@ user3386109注释过,if语句不是必需的,但是这段代码似乎试图实现Fisher-Yates shuffle

答案 1 :(得分:1)

rand的返回值范围从零到RAND_MAX。因此,使用实数算法将其除以RAND_MAX+1会得到[0,1)的值。 (这是从0到1的数字间隔,包括0且不包括1。)如果将其乘以 x ,它将是[0, x )。

因此,使用实数算法,rand() / (RAND_MAX+1) * (curr_pos-i)将在[0,curr_pos-i中给出一个数字)。该表达式等效于rand() / ((RAND_MAX+1)/(curr_pos-i)),并且与代码rand() / (RAND_MAX/(curr_pos-i) + 1)中的表达式非常相似。因此,我们有一个关于要执行的操作的线索:它可能正在尝试在[0,curr_pos-i)中生成一个随机数。

差异是由于使用整数算术而不是实数算术引起的。如果我们使用代码rand() / ((RAND_MAX+1)/(curr_pos-i)),则将curr_pos-i除以四舍五入,这可能会使最终结果大于我们想要的结果;它可以包含curr_pos-i而不是排除它。

相反,代码使用RAND_MAX/(curr_pos-i) + 1作为商。请注意,如果RAND_MAX/(curr_pos-i)中的除法四舍五入,则会丢弃小于1的分数。因此加1意味着结果必然大于实数商RAND_MAX/(curr_pos-i)。因此rand() / ((RAND_MAX+1)/(curr_pos-i))不能等于curr_pos-i;它必须小于它。

现在我们知道rand() / ((RAND_MAX+1)/(curr_pos-i))在[0,curr_pos-i中生成一个数字)。然后将i添加到此,将在[icurr_pos)中产生一个数字。

由于将总和分配给j,因此swap(&array[j], &array[i]);array[i](包括i)交换到curr_pos(排除)的其他数组元素交换了for (int i = 0; i < curr_pos-1; i++)

由于这是在循环curr_pos中完成的,因此array之前的数组中的每个元素都将与“随机”元素(可能是本身)交换。结果是将curr_pos之前的RAND_MAX中的所有元素洗牌。

(要注意的一件事是,由于整数算术的截断和<div class="modal fade" id="myModal" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <?php $text = '<div class="fetched-data"></div>'; echo $text; ?> <div class="modal-body"></div> </div> </div> </div> </div> 的因素数量有限,因此选择的“随机”数的分布将有一些不规则性。可能不会均匀地分布在所有可能的混洗中。)