我们先来看题目描述:
已知有个 rand7() 的函数,返回 1 到 7 随机自然数,怎样利用这个 rand7() 构造 rand10(),随机 1 ~ 10。
产生随机数的主要原则是每个数出现的概率是相等的,如果可以得到一组等概率出现的数字,那么就可以从中找到映射为 1 到 10 的方法。
rand7() 返回 1 ~ 7 的自然数,构造新的函数 (rand7() - 1) * 7 + rand7(),这个函数会随机产生 1 到 49 的自然数。
原因是 1 到 49 中的每个数只有唯一的第一个 rand7() 的值和第二个 rand7() 的值表示,于是它们出现的概率是相等。
但是这里的数字太多,可以丢弃 41 到 49 的数字,把 1 到 40 的数字分成 10 组,每组映射成 1 到 10 中的一个,于是可以得到随机的结果。
具体方法是,利用 (rand7() - 1) * 7 + rand7() 产生随机数 x,如果大于 40 则继续随机直到小于等于 40 为止,如果小于等于 40,则产生的随机数为 (x - 1) / 4 + 1。