long long x[1000000], n, small, big;
main(){
cin >> n; //range
cin >> small; cin >> big;
srand(time(NULL));
for (int i=0; i<n; i++){
x[i]=small + rand()%(big-small+1);
}
merge_sort(x,0,n-1);
for (int i=0; i<n; i++){
cout << x[i] << " ";
}
}
(忽略merge_sort,我只用它来查看最高的数字)
所以我确保所有变量都在 long long 中,但是所有随机x [i]都不会通过整数范围(32768)。有人知道为什么吗?
答案 0 :(得分:1)
与所有随机数生成器一样,std::rand()
会生成有限范围内的数字。所有值均大于或等于0,并且所有值均小于或等于RAND_MAX
。 RAND_MAX
的值取决于您使用的实现。您可以查看它以查看上限:
std::cout << RAND_MAX << '\n';
有些技术可以根据随机数生成器的结果创建更大或更小的范围。使用较新的<random>
类,您将使用std::uniform_int
处理细节。使用std::rand()
,您必须滚动自己的代码。
要缩小范围,大多数人的本能是使用其余的部分,就像问题中的代码一样。可以,但是可能会导致失真。举一个极端的例子,假设RAND_MAX
是32767,并且您想生成[0 .. 32766]
范围内的值。因此,您使用rand() % 32767
,它将为您提供该范围内的值。 但是存在一个问题:每当rand()
产生0时,您将得到0;当它产生1时,您将得到1,依此类推,直到32766。但是当rand()
产生32767,您得到0。也就是说,rand()
产生0 时得到0,产生32767,但是您只从{{ 1}}。如果rand()
完全统一(没有RNG),则您获得0的频率是获得其他任何值的两倍。当您要生成的范围比RNG生成的总范围小得多时,这种失真就不会那么大,并且可以接受。
要正确执行此操作,必须丢弃值。丢弃值的最简单方法是忽略大于所需值的值:
rand()
但是如果int res = rand();
while (res > my_max_value)
res = rand();
很小,这将丢弃很多值,浪费大量时间。因此,更好的方法是将丢弃与余下的部分结合起来:
my_max_value
我没有正确地进行计算;例如,如果int max = ((RAND_MAX + 1) / my_max_value) * my_max_value;
int res = rand();
while (res >= max)
res = rand();
res %= my_max_value;
等于RAND_MAX
,则加1将溢出。剩下的修正工作供读者练习。
INT_MAX
将是max
的最大倍数,小于或等于my_max_value
。该代码将丢弃大于或等于该值的值,并在找到合适的值时将剩余的值保留。
要创建一个大于RNG范围的范围,请“平铺”多个值。例如,如果RAND_MAX
是32767,并且您需要RAND_MAX
范围内的值(上限是(32767 << 15)+ 32767),则您将两次调用[0 .. 1073741823]
,将其移位1剩下15个结果,然后加上另一个结果。如果您没有这么方便的
请注意,无论您使用哪种RNG,都必须完成所有操作。当所有这些计算都封装在rand()
中时,在C ++ 11中更加方便,这是使用C ++ 11 RNG和发行版的一个很好的理由。