假设有如下两个函数 rand3()可以产生随机的0 1 2,rand5()可以产生随机的0 1 2 3 4,现在请你利用它编写一个函数rand7(),产生0~6的随机数
为了使随机数字产生的概率均等:
int rand7()
{
int sum=0;
sum+=rand3();//0,1,2
sum+=rand3()+3;//3,4,5
sum+=rand3()+6;//6,7,8
sum+=rand5()+9;//9,10,11,12,13
sum%=7;//0,1,2,3,4,5,6
return sum;
}
rand7=rand3+rand5
rand7=rand3+rand3+rand3
rand7=rand3*2+rand3
rand7=rand3*3-rand5
应该还有一些,
int rand7()
{
int x5 = 7;
while (x5 > 6)
{
int x3 = 2;
while (x3 > 1)
{
x5 = rand(5);
if (x3 == 1) x5 = x5 + 5;
if (x5 < 7) return x5;
}
}
}
int a=rand5+rand5+…+rand5 + rand3+…+rand3
return a%8;
个数自己决定。
第一枚骰子有三种可能,第二枚骰子有五种可能,排列组合有十五种可能,取其中的七种或十四种,剩下的抛弃不就行了,只要保证七分之一或者十四分之一,反正是电脑运行,有什么资源浪费的
int rand7()
{
int x5 = rand5();
int x3 = rand3();
while (x5 ==x3 ) {
int x3 = rand3();
}
return x5+x3;
}
int rand7()
{
int x5 = rand5();
int x3 = rand3();
while (x5 ==x3 ) {
x3 = rand3();
}
return x5+x3;
}
int rand7()
{
int x3=rand3();
int x5=rand5();
if(x3=x5)
return x3;//或者return x5;
else
return x3+x5;
}
这样不知道行不行
int rand7() {
int sum = 0;
for (int i=0;i<7*5;i++) {
sum+= rand3()+i*3;
}
for(int i=0;i<7*3;i++) {
sum += rand5()+i*5;
}
return sum%7;
}
参考了楼上的
int rand7(){
bool flag = true;
while(flag){
flag = false;
int a = rand3()+rand5();
int b;
if(a==0||a==6)//处理0、6
return a;
else if(a==1||a==5)//处理1、5
{
while(true){
b = rand3();
if(b==0)
return a;
else if(b==1)
{
flag = true;
break;
}
}
}
else{//处理2、3、4
b = rand3();
if(b==0)
return a;
else
flag = true;
}
}
}
不是那么完美:
int rand7()
{
int sum;
switch(rand3())
{
case 0:
sum=rand5();//0,1,2,3,4
break;
case 1:
sum=rand5()+5;//5,6,7,8,9
break;
case 2:
do
{
sum=rand5()+10;//10,11,12,13,14
}while(sum!=14);
break;
}
sum%=7;//0,1,2,3,4,5,6
return sum;
}
优化了的方法
//从均匀的0~20里面取mod
int rand7() {
int sum = 0;
for (int i=0;i<7;i++) {
sum+= rand3()+i*3;
}
return sum%7;
}
//从均匀的0~34里面取mod
int rand7() {
int sum = 0;
for(int i=0;i<7;i++) {
sum += rand5()+i*5;
}
return sum%7;
}
调用rand3函数7次,统计某一个数字(例如0)在其中出现的的次数,将次数作为随机数
int rand7(){
int count = 0;
--这里统计数字0出现的次数
for(i=0;i<7;i++){
int b = rand3();
if(b==0){
count ++;
}
}
return count;
}
利用预置数组
int rand7(){
int a[][]={
0,1,2,
3,4,5,
6,0,1,
2,3,4,
5,6,7}
int row=rand5;
int col =rand3 ;
int rand7=7;
while(rand7=7){
rand7=a[row][col];
}
return rand7;
}
利用预置数组
int rand7(){
int a[][]={
0,1,2,
3,4,5,
6,0,1,
2,3,4,
5,6,7}
int row=rand5;
int col =rand3 ;
int rand7=7;
while(rand7=7){
rand7=a[row][col];
}
return rand7;
}
int rand7()
{
return rand3() + rand5();
}
int rand7()
{
return rand3() + rand5();
}
原理:
rand3 ——》0,1,2
rand5 ——》0,1,2,3,4
两者最大值为2+4=6
两者最小值为0+0=0
因为是随机数,因此无需知道每次都是多少,只要结果正确即可。即rand3+rand5
看了这么多答案,也真是挺让人眼花的,各种类型的都有,按概率偏差的特点可以分为: 单峰形、双峰形、递减形、起伏形,真是万紫千红啊!其实已经有网友提供了一个正确的答案,各位自行查找。
我就按99999次统计算来测试,看看以上各位能不能对得上号,第一组数据 Test rand5 9999 是正常的测试,作为对比组:
Test rand5 9999
0 -> 2024 20.24%
1 -> 1972 19.72%
2 -> 2019 20.19%
3 -> 1989 19.89%
4 -> 1995 19.95%
Test rand7 99999
0 -> 13457 13.46%
1 -> 17075 17.08%
2 -> 18373 18.37%
3 -> 17059 17.06%
4 -> 13332 13.33%
5 -> 10401 10.40%
6 -> 10302 10.30%
Test rand7a 99999
1 -> 19865 19.87%
2 -> 20100 20.10%
3 -> 26499 26.50%
4 -> 13475 13.48%
5 -> 13320 13.32%
6 -> 6740 6.74%
Test rand7b 99999
0 -> 6621 6.62%
1 -> 13241 13.24%
2 -> 19854 19.85%
3 -> 19984 19.98%
4 -> 20137 20.14%
5 -> 13399 13.40%
6 -> 6763 6.76%
Test rand7c 99999
0 -> 46422 46.42%
1 -> 13540 13.54%
2 -> 13346 13.35%
3 -> 6675 6.68%
4 -> 6602 6.60%
5 -> 6687 6.69%
6 -> 6727 6.73%
Test rand7d 99999
0 -> 17897 17.90%
1 -> 16879 16.88%
2 -> 13466 13.47%
3 -> 10974 10.97%
4 -> 10920 10.92%
5 -> 13499 13.50%
6 -> 16364 16.36%
Test rand7e 99999
0 -> 14284 14.28%
1 -> 14205 14.21%
2 -> 14245 14.25%
3 -> 14409 14.41%
4 -> 14316 14.32%
5 -> 14347 14.35%
6 -> 14193 14.19%
Test rand7f 99999
0 -> 3708 3.71%
1 -> 11277 11.28%
2 -> 22269 22.27%
3 -> 25953 25.95%
4 -> 22133 22.13%
5 -> 10943 10.94%
6 -> 3716 3.72%
看了各位算法经测试,楼上预置数组的方法是正确的:
#include<stdlib.h>
#include<stdio.h>
#include <time.h>
int rand5()
{
return rand()%5;
}
int rand3()
{
return rand()%3;
}
int rand7()
{
int a[5][3]={
0,1,2,
3,4,5,
6,0,1,
2,3,4,
5,6,7};
int row,col;
do
{
row = rand5();
col = rand3();
} while(a[row][col]==7);
return a[row][col];
}
int main()
{
int re[7]={0};
srand( (unsigned)time( NULL ) );
for(int i=0;i<100000;i++)
{
re[rand7()]++;
}
for(int i=0;i<7;i++)
printf("re[%d]=%d, %2d%%\n",i,re[i],int(re[i]/1000.0+0.5));
return 0;
}
哎
int rand7() {
while (true) {
switch (rand3()) {
case 0:
return rand3(); //0,1,2
case 1:
return rand3()+3; //3,4,5
case 2:
if (rand3()) { // 取到7,8重新取
continue;
}
return 6; // 6
}
}
}
修正:
int rand7()
{
int sum;
do
{
switch(rand3())
{
case 0:
sum=rand5();//0,1,2,3,4
break;
case 1:
sum=rand5()+5;//5,6,7,8,9
break;
case 2:
sum=rand5()+10;//10,11,12,13,14
break;
}
}while(sum==14);
sum%=7;//0,1,2,3,4,5,6
return sum;
}
关于这个问题,结合各家给的参考答案,我专门写了一篇博文,有兴趣可以移驾《一个随机数引发的血案》:http://blog.csdn.net/WinsenJiansbomber/article/details/50604653
这个更简单点:
int rand7()
{
int re;
do
{
re=rand3()+rand3()*3;
}while(re>6);
return re;
}