3 回答
TA贡献1946条经验 获得超4个赞
要真正正确,实际上要比大多数人意识到的要难一些:
int rand_lim(int limit) {
/* return a random number between 0 and limit inclusive.
*/
int divisor = RAND_MAX/(limit+1);
int retval;
do {
retval = rand() / divisor;
} while (retval > limit);
return retval;
}
仅仅使用%(或等价地/)获得一个范围内的数字的尝试几乎不可避免地会引起偏斜(即,某些数字会比其他数字更频繁地生成)。
至于为什么使用%会产生偏斜的结果:除非您想要的范围是RAND_MAX的除数,否则偏斜是不可避免的。如果您从小数字开始,那么很容易明白为什么。考虑拿10块糖果(我们假设您不能将它切成小块,切成小块),然后尝试将其平均分配给三个孩子。显然,这是不可能的-如果您分发所有糖果,则最接近的是两个孩子得到三块糖果,其中一个得到四个。
所有孩子得到相同数量的糖果的唯一途径是:确保您根本不分发最后一块糖果。
要将其与上面的代码相关联,让我们从对糖果进行编号(从1到10)和对孩子进行编号(从1到3)开始。初始除法说,由于有3个孩子,因此除数为3。然后,我们从桶中取出一个随机的糖果,查看它的数量并除以三,然后交给那个孩子-但是,如果结果大于3(即我们选出了10号糖果),我们就不会完全交给我们-我们将其丢弃并拿出另一个糖果。
当然,如果使用的是C ++的现代实现(即,支持C ++ 11或更高版本的实现),则通常应使用distribution标准库中的类之一。上面的代码与最为接近std::uniform_int_distribution,但是标准库还包括uniform_real_distribution以及许多非均匀分布的类(Bernoulli,Poisson,正态分布,也许还有一些我现在不记得的分布)。
TA贡献1866条经验 获得超5个赞
int rand_range(int min_n, int max_n)
{
return rand() % (max_n - min_n + 1) + min_n;
}
对于分数:
double rand_range(double min_n, double max_n)
{
return (double)rand()/RAND_MAX * (max_n - min_n) + min_n;
}
TA贡献2012条经验 获得超12个赞
我是在Obj-C中专门为iPhone项目编写的:
- (int) intInRangeMinimum:(int)min andMaximum:(int)max {
if (min > max) { return -1; }
int adjustedMax = (max + 1) - min; // arc4random returns within the set {min, (max - 1)}
int random = arc4random() % adjustedMax;
int result = random + min;
return result;
}
使用方法:
int newNumber = [aClass intInRangeMinimum:1 andMaximum:100];
加盐调味
- 3 回答
- 0 关注
- 391 浏览
添加回答
举报