3 回答

TA貢獻(xiàn)1946條經(jīng)驗(yàn) 獲得超4個(gè)贊
要真正正確,實(shí)際上要比大多數(shù)人意識(shí)到的要難一些:
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;
}
僅僅使用%(或等價(jià)地/)獲得一個(gè)范圍內(nèi)的數(shù)字的嘗試幾乎不可避免地會(huì)引起偏斜(即,某些數(shù)字會(huì)比其他數(shù)字更頻繁地生成)。
至于為什么使用%會(huì)產(chǎn)生偏斜的結(jié)果:除非您想要的范圍是RAND_MAX的除數(shù),否則偏斜是不可避免的。如果您從小數(shù)字開始,那么很容易明白為什么??紤]拿10塊糖果(我們假設(shè)您不能將它切成小塊,切成小塊),然后嘗試將其平均分配給三個(gè)孩子。顯然,這是不可能的-如果您分發(fā)所有糖果,則最接近的是兩個(gè)孩子得到三塊糖果,其中一個(gè)得到四個(gè)。
所有孩子得到相同數(shù)量的糖果的唯一途徑是:確保您根本不分發(fā)最后一塊糖果。
要將其與上面的代碼相關(guān)聯(lián),讓我們從對(duì)糖果進(jìn)行編號(hào)(從1到10)和對(duì)孩子進(jìn)行編號(hào)(從1到3)開始。初始除法說(shuō),由于有3個(gè)孩子,因此除數(shù)為3。然后,我們從桶中取出一個(gè)隨機(jī)的糖果,查看它的數(shù)量并除以三,然后交給那個(gè)孩子-但是,如果結(jié)果大于3(即我們選出了10號(hào)糖果),我們就不會(huì)完全交給我們-我們將其丟棄并拿出另一個(gè)糖果。
當(dāng)然,如果使用的是C ++的現(xiàn)代實(shí)現(xiàn)(即,支持C ++ 11或更高版本的實(shí)現(xiàn)),則通常應(yīng)使用distribution標(biāo)準(zhǔn)庫(kù)中的類之一。上面的代碼與最為接近std::uniform_int_distribution,但是標(biāo)準(zhǔn)庫(kù)還包括uniform_real_distribution以及許多非均勻分布的類(Bernoulli,Poisson,正態(tài)分布,也許還有一些我現(xiàn)在不記得的分布)。

TA貢獻(xiàn)1866條經(jīng)驗(yàn) 獲得超5個(gè)贊
int rand_range(int min_n, int max_n)
{
return rand() % (max_n - min_n + 1) + min_n;
}
對(duì)于分?jǐn)?shù):
double rand_range(double min_n, double max_n)
{
return (double)rand()/RAND_MAX * (max_n - min_n) + min_n;
}

TA貢獻(xiàn)2012條經(jīng)驗(yàn) 獲得超12個(gè)贊
我是在Obj-C中專門為iPhone項(xiàng)目編寫的:
- (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];
加鹽調(diào)味
- 3 回答
- 0 關(guān)注
- 442 瀏覽
添加回答
舉報(bào)