7随机到10随机
已有方法 rand7
可生成 1 到 7 范围内的均匀随机整数,试写一个方法 rand10
生成 1 到 10 范围内的均匀随机整数。
int rand10() {
int n;
do{
n= (rand7()-1)*7+rand7()-1;//生成[0,48]之前的等概率随机数。
}while(n>=40);//筛选出[0,39]内的数,因为要获取[1,10],就要先获取[0,9],就要通过x%10获取,为了使得[0,9]出现等概率,x属于[0,9]/[10,19]/[20,29]均可,为了最容易出数,取最大范围[0,39]
return n%10+1;
}
不等概率随机到等概率随机
const float absError = 1e-6;
bool isEquire(float a, float b) {
return fabs(a - b) < absError;
}
int rand01p() {
float p = 0.87;//p值任意指定
float randomGet = ((float)(rand() % 1000)) / 1000;
return (randomGet < p || isEquire(randomGet, p)) ? 0 : 1;
}
用rand01p()生成rand1_6(),等概率生成[1,6]内的整数。
因为生成01和10的概率p(1-p)和(1-p)p是相等的,所以先可以等概率产生0或1,即等概率获得[0,1]内的数:
int random01() {
int get01;
do {
get01 = random01p();
} while (get01 == random01p());//当两次random的结果不为p(1-p)或(1-p)p时继续
return get01;//等概率生成0或1
}
用插空法迭代生成目标范围:(有几个数就扩大几倍插空)
int random03() {
return random01() * 2 + random01();//等概率生成[0,3]内的整数。
}
筛选:
int random1_6() {
int randomGet;
do {
randomGet = random03() * 4 + random03();//等概率生成[0,15]内的整数。
} while (randomGet >= 12);
return randomGet % 6+1;
}