读书人

200分!随机数有关问题

发布时间: 2012-02-19 19:43:39 作者: rapoo

200分!随机数问题。
rand7是一个能生成1-7的随机数。要求利用rand7生成1-10的随机数。
之前看过这贴子,找不到了。。。再来问问。
要求:
不可以用这样的方法: 生成rand7() 如果 rand7()>5。重新来过。我的意思是要确保你的函数在任何的情况下都能在一个流程产生结果(可以用多次rand7())。总之就是不准有无限递归或循环。

另求 c++ 的开发 android 的教程。

[解决办法]
A1=INT(RAND()*(12-7)+7) 复制或下拉得出随机整数
[解决办法]
......

rand7()如果是随机的话,那么rand10就很好写啊。。。

int rand10()
{
return rand7()*rand7()*rand7()%10+1; //返回区间[1,10]

[解决办法]
return rand7()*rand7()*rand7()%10+1; //返回区间就是[1,10]
[解决办法]
百度面试出过这个题目。上面回答的根本不随机
[解决办法]
其实只要能生成0,1,就可以生成任意范围的数字
[解决办法]
rand()与srand()形影相随,前者产生1-RAND_MAX(在stdlib.h中定义的宏)之间随机整数,后者产生种子值。srand(int XXX)给定一个种子值后,再调用rand(),则rand()给出的随机数序列是确定的,这个随机数序列随种子值的改变而改变,可以修改XXX进行验证。

请参考并调试运行我在linux下的C代码:

1 /*rand.c*/
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <time.h>
6
7 int main(int argc, char **argv)
8 {
9 srand((int)(time(0)));//产生种子值
10 int i, j;
11 /*打印出随机数序列中的前十个数字*/
12 for(i = 0; i < 10; i++)
13 {
14 j = 1 + (int)(7.0 * rand() /(RAND_MAX + 1.0));//调用rand(),并产生1-7的随机数
15 printf("%d\t", j);
16 }
17 printf("\n");
18
19 return 0;
20 }

祝君不断进步!

[解决办法]
我一面就这个题,要用组合数学做,不是算术。
[解决办法]
http://blog.csdn.net/ljsspace/article/details/6820753
[解决办法]
楼主不希望丢弃?
那就用这个吧

C/C++ code
int rand10(){  int sum=0;     for(int i=0; i<10; i++)      sum=7*sum+rand7()-1;  return sum%10+1;}
[解决办法]
探讨

return rand7()*rand7()*rand7()%10+1; //返回区间就是[1,10]

[解决办法]
简单说一下10楼的思路
循环结束后,得到的sum是位于[0,6666666666]之间的均匀分布的随机数(注意这里是7进制表示)
注意6666666666能被10整除,后面那句return相信楼主肯定懂了
[解决办法]
探讨

楼主不希望丢弃?
那就用这个吧
C/C++ code

int rand10()
{
int sum=0;
for(int i=0; i<10; i++)
sum=7*sum+rand7()-1;
return sum%10+1;
}

[解决办法]
探讨

楼主不希望丢弃?
那就用这个吧
C/C++ code

int rand10()
{
int sum=0;
for(int i=0; i<10; i++)
sum=7*sum+rand7()-1;
return sum%10+1;
}

[解决办法]
7的任何次方都不能被10整除~
探讨

简单说一下10楼的思路
循环结束后,得到的sum是位于[0,6666666666]之间的均匀分布的随机数(注意这里是7进制表示)
注意6666666666能被10整除,后面那句return相信楼主肯定懂了

[解决办法]
假定rand7()得到的1~7是绝对意义上均匀分布的,那么我认为用%(取模)的办法,不可能得到绝对意义上的1~10之间的均匀分布的随机数。
[解决办法]
还是把rand7放大10/7倍比较好
[解决办法]
搞错了
1-7的区间长度是6,1-10区间长度是9,刚好是1.5倍,很容易扩大的
(rand7() - 1 ) * 1.5 + 1
[解决办法]
不好意思,之前答非所问了。

1 /*rand10.c*/
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <time.h>
6
7 int rand7(void);
8 int rand10();
9
10 int main(int argc, char **argv)
11 {
12 printf("%d\n", rand10());
13
14 return 0;
15 }
16
17 int rand7()
18 {
19 int i;
20 srand((int)(time(0)));
21 i = 1 + (7.0 * rand()/ (RAND_MAX + 1.0));
22
23 return i;
24
25 }
26
27 int rand10()
28 {
29 return 1 + (int)((float)(rand7() * rand7()) / 5.0);
30 }

[解决办法]

探讨
引用:

楼主不希望丢弃?
那就用这个吧
C/C++ code

int rand10()
{
int sum=0;
for(int i=0; i<10; i++)
sum=7*sum+rand7()-1;
return sum%10+1;
}


这个能确保结果会在[1, 10]之间均匀分布吗?表示非常怀疑。请mstlq证明一下。

[解决办法]
仅使用确定次数循环的办法,是无法达到楼主要求的……
因为绝对的rand7()在指定循环n的情况下,只能实现绝对的rand7^n()功能
很可惜 7^n不可能被10整除
[解决办法]
探讨
引用:

楼主不希望丢弃?
那就用这个吧
C/C++ code

int rand10()
{
int sum=0;
for(int i=0; i<10; i++)
sum=7*sum+rand7()-1;
return sum%10+1;
}

这个方法只能近似随机。
产生的是0-282475248之间的数,然后%10+1。出现0-8的……

[解决办法]
rand7() * rand7() * rand7() * rand7() * rand7() * rand7() * rand7() + rand7() - 1所产生的数字在1 ~ 823549之间,且是均匀分布的。那么这些数字的个位数0 ~ 9 也是均匀分布的(不是真正意义上的均匀分布,个位为0的数字少出现了一次,但只要823549这样的数字足够大,可以认为是均匀分布)。

那么求出rand7() * rand7() * rand7() * rand7() * rand7() * rand7() * rand7() + rand7() - 1的个位数字再加1就可以认为得到的数字在1~10之间均匀分布。
[解决办法]
探讨

rand7() * rand7() * rand7() * rand7() * rand7() * rand7() * rand7() + rand7() - 1所产生的数字在1 ~ 823549之间,且是均匀分布的。那么这些数字的个位数0 ~ 9 也是均匀分布的(不是真正意义上的均匀分布,个位为0的数字少出现了一次,但只要823549这样的数字足够大,可以认为是均匀分布)。

那么求出ra……

[解决办法]
到目前为止,我认为如果rand7()是绝对意义上在[1, 7]均匀分布,那么24楼的做法所得到的随机数,在[1, 10]上也是绝对意义上的均匀分布。

欢迎批评指正。
[解决办法]
探讨

引用:
rand7() * rand7() * rand7() * rand7() * rand7() * rand7() * rand7() + rand7() - 1所产生的数字在1 ~ 823549之间,且是均匀分布的。那么这些数字的个位数0 ~ 9 也是均匀分布的(不是真正意义上的均匀分布,个位为0的数字少出现了一次,但只要823549这样的数字……

[解决办法]
探讨
引用:
引用:
rand7() * rand7() * rand7() * rand7() * rand7() * rand7() * rand7() + rand7() - 1所产生的数字在1 ~ 823549之间,且是均匀分布的。那么这些数字的个位数0 ~ 9 也是均匀分布的(不是真正意义上的均匀分布,个……



[解决办法]
探讨

引用:
引用:
rand7() * rand7() * rand7() * rand7() * rand7() * rand7() * rand7() + rand7() - 1所产生的数字在1 ~ 823549之间,且是均匀分布的。那么这些数字的个位数0 ~ 9 也是均匀分布的(不是真正意义上的均匀分布,……

[解决办法]
探讨
引用:

引用:
引用:
rand7() * rand7() * rand7() * rand7() * rand7() * rand7() * rand7() + rand7() - 1所产生的数字在1 ~ 823549之间,且是均匀分布的。那么这些数字的个……

[解决办法]
探讨

引用:

rand7() * rand7() * rand7() * rand7() * rand7() * rand7() * rand7() + rand7() - 1所产生的数字在1 ~ 823549之间,且是均匀分布的。那么这些数字的个位数0 ~ 9 也是均匀分布的(不是真正意义上的均匀分布,个位为0的数字少出现了一次,但只要823549这样的……

[解决办法]
Android上的应用开发,大部分情况下是用Java,主要是因为界面逻辑处理的问题,Google在这方面已经做了很多工作。如果不考虑界面用C、C++也应该是可以的。用纯C/C++做,估计难度挺大的,除非有相关的库。

俺曾经翻译过一个篇文章:
Step by Step搭建Android NDK开发环境

这篇文章写得不错,可以参考一下。主要是介绍了NDK的环境搭建。

拙作:用Android NDK实现四则运算就是在上一篇文章的基础上,用C/C++模拟业务逻辑处理,然后在Android上用Java调用它。

仅供参考。
[解决办法]
探讨

“rand7() * rand7() * rand7() * rand7() * rand7() * rand7() * rand7() + rand7() - 1所产生的数字在1 ~ 823549之间,且是均匀分布的。”

这个前提我的直觉告诉我,肯定错。

另外,rand7产生随机数的奇数的率是4/7;
rand7() * rand7() * rand7() * rand7() *……

[解决办法]
探讨

如果你要产生一个很大的数,我觉得还是板主大人的做法比较合适。

[解决办法]
探讨

引用:

我觉得兄台说法似有不妥。


奇偶分布不均匀,没不妥啊。。。

[解决办法]
对于rand7() * rand7() * rand7() * rand7() * rand7() * rand7() * rand7()产生奇数或者偶数这样的事件,是不能用独立概率来算的。
[解决办法]
探讨
引用:

引用:

我觉得兄台说法似有不妥。


奇偶分布不均匀,没不妥啊。。。



引用:

“rand7() * rand7() * rand7() * rand7() * rand7() * rand7() * rand7() + r……

[解决办法]
探讨
引用:

引用:

我觉得兄台说法似有不妥。


奇偶分布不均匀,没不妥啊。。。



引用:

“rand7() * rand7() * rand7() * rand7() * rand7() * rand7() * rand7() + r……

[解决办法]
int rand10()
{
int a;
do a=rand7();
while(a>6);//产生a在1-5;
if(rand7()%2==0)
a+=5;//产生a在6-10
return a;
}
另外问下如何回复使代码在里面的
[解决办法]
学java的飘过
[解决办法]
当然是丢掉一个数啊。不要玩不丢数的飞机。
反正计算机产生的随机数本来就是伪随机的。大致差不多就行了。

探讨
引用:
个人觉得奇偶没什么关系,只是7的成方差生的数,后面还有一个+rand7()嘛


问题是在于后面的那个rand7是产生奇数的偶数的概率是不相等的。

[解决办法]
好贴 学习了
------解决方案--------------------


探讨

引用:

这样一来,产生奇数和产生偶数的概率都等于0了,那么到底产生了什么数字?难道既不是奇数又不是偶数?
因此,这样计算产生奇数和偶数的概率,个人认为是不正确的。请指正。


如上面所说。0也是偶数,只要rand7() * rand7() * rand7() * rand7() * rand7() * rand7() * rand7()

……

[解决办法]
每天回帖即可获得10分可用分
[解决办法]
好厉害啊
[解决办法]
mark
[解决办法]
完满的答案需要严格的数学论证,但在生产中用rand7()实现rand10(),以下代码基本够用。
之前很粗心地回答了两次,感觉很不妥,再稍作修改,粘贴一次。
贻笑大方了,但我确实跟着有了许多收获,呵呵……

1 /*rand10.c*/
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <time.h>
6
7 int rand7(void);
8 int rand10();
9
10 int main(int argc, char **argv)
11 {
12 printf("%d\n", rand10());
13
14 return 0;
15 }
16
17 int rand7()
18 {
19 int i;
20 srand((int)(time(0)));
21 i = 1 + (7.0 * rand()/ (RAND_MAX + 1.0));
22
23 return i;
24
25 }
26
27 int rand10()
28 {
29 int i;
30 i = rand() % 3;
31 if (0 == i)
32 return rand7() + 3;
33 else
34 return rand7();
35 }

[解决办法]
探讨
完满的答案需要严格的数学论证,但在生产中用rand7()实现rand10(),以下代码基本够用。
之前很粗心地回答了两次,感觉很不妥,再稍作修改,粘贴一次。
贻笑大方了,但我确实跟着有了许多收获,呵呵……

1 /*rand10.c*/
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <time.……

[解决办法]
探讨
rand7() * rand7() * rand7() * rand7() * rand7() * rand7() * rand7() + rand7() - 1所产生的数字在1 ~ 823549之间,且是均匀分布的。

[解决办法]
探讨
坚决不丢。。。


[解决办法]
rand10(){
3*rand()\2
}
可以否
[解决办法]
up!
[解决办法]
一种近似解决方案:

先产生n个随机数,每个数编码成(0,1,2,3 ,4,5,6),然后将这n个数连起来,形成一个7进制数。

再转换成10进制数,最后结果的个位数应该就近似为一个0-9的随机数。 n越大,精度越高。

证明:

产生的n位7进制数,取值范围是(0-(7^n-1)),取到每个数的概率都是相等的 p=1/(7^n)。

现在把取值范围平均分配为7份,每一份的概率就约等于1/7 。

也就是n越大的时候近似度就越高!呈指数级增长 ^ ^
所以就用这种办法代替

int rand7();//返回一个1-7的数

int rand10()
{
int i = rand7()-1;//0-6

int j = rand7()-1;//0-6

i = i*7+j; //产生7*7=49种结果 只要i j均匀分布 0---48就均匀分布

//产生一个00-66(7进制数,相当于10进制的0-48)

//其中0-48出现的概率相等。

if(i>=40) //此处从0开始到39

return rand10();

else//0-39出现的概率相等

return i%10 + 1; //

}


[解决办法]
rand7()+rand7()%4;
------解决方案--------------------


rand() 加起来 再求模肯定是不对的,因为根据基础概率论,多个均匀分布相加必然趋向于 正态分布,不再是均匀分布咯~
[解决办法]
接分 接分 接分
[解决办法]
其实我是来打酱油的哦~
[解决办法]
http://blog.csdn.net/ljsspace/article/details/6820753
[解决办法]
我回去翻书看看概率统计好了
[解决办法]
不好意思,我是赚积分来的
[解决办法]
既然能生成1-7,只要加各种权重和运算就能生成1-10
[解决办法]

探讨

引用:
引用:
坚决不丢。。。



坚决不丢,理论上无解……
丢,理论上没任何问题

楼主可以试想下面的问题,怎么由rand3()函数做一个rand2()?
很显然, 下面的程序就足够解决问题了

int rand2()
{
int re = rand3();
while(re==3)
……

[解决办法]
还是把rand7放大10/7倍比较好

[解决办法]
还是把rand7放大10/7倍比较好

[解决办法]
探讨

还是把rand7放大10/7倍比较好

[解决办法]
C/C++ code
int rand7(){    srand(time(NULL));    return rand()%7+1;}int rand10(){    return rand7()+rand7()%3+1;}
[解决办法]
路过,学些了
[解决办法]
#include<iostream>
using std::cout;
using std::endl;
int main()
{

int a= rand()%7+rand()%4;
cout<<a<<endl;
return 0;
}
抄的65楼的
[解决办法]
#include<iostream>
using std::cout;
using std::endl;
int main()
{

int a= rand()%8+rand()%4;//rand7我在2005上怎么也用不出来,只能用rad()%8代替了。
cout<<a<<endl;
return 0;
}
更正上面的
[解决办法]
不懂。
如果rand7绝对能均匀分布了,那rand7+1不也能绝对分布吗?那还纠结什么?
[解决办法]
(
rand7()+rand7()+rand7()+rand7()+rand7()+rand7()+rand7()+rand7()+rand7()+rand7()
)
%10
不行吗?为什么都想到乘了?
[解决办法]
上面是假设rand7==random(7),即0-6
[解决办法]
灌水,灌水,灌水,灌水,灌水,灌水,灌水,灌水,灌水,灌水,灌水,灌水,灌水,灌水,灌水,
[解决办法]
探讨
rand7是一个能生成1-7的随机数。要求利用rand7生成1-10的随机数。
之前看过这贴子,找不到了。。。再来问问。
要求:
不可以用这样的方法: 生成rand7() 如果 rand7()>5。重新来过。我的意思是要确保你的函数在任何的情况下都能在一个流程产生结果(可以用多次rand7())。总之就是不准有无限递归或循环。

另求 c++ 的开发 android 的教程。

[解决办法]
路过。。。
[解决办法]
探讨
(
rand7()+rand7()+rand7()+rand7()+rand7()+rand7()+rand7()+rand7()+rand7()+rand7()


)
%10
不行吗?为什么都想到乘了?


[解决办法]
探讨
引用:
(
rand7()+rand7()+rand7()+rand7()+rand7()+rand7()+rand7()+rand7()+rand7()+rand7()
)
%10
不行吗?为什么都想到乘了?

不行,举个简单例子给兄弟类比一下
两个骰子一起扔,可以扔出2-12的结果……
如果两骰子点数加起来等于2的概率和等于7的概率一样的……

[解决办法]
随机函数产生的是伪随机数
[解决办法]
我有个笨方法,不过能满足LZ的要求,具体思路是:既然rand7()是随机的,那么rand7() + (rand7() + 7)即是rand14(),同理rand7() + (rand7() + 7 * 1) + (rand7() + 7 * 2)即是rand21(),依此类推可得rand70为
for(int i = 0; i < 10; i++){
sum += rand7() + i * 7;
},所以就有以下代码,经测试完全随机,且不用递归和无限循环。
C# code
int rand70(){    int sum = 0;    for(int i = 0; i < 10; i++){        sum += rand7() + i * 7;    }    return sum;}int rand10(){    int ret = rand70() % 10;    if(ret == 0){        ret = 10;    }    return ret;}
[解决办法]
探讨

我有个笨方法,不过能满足LZ的要求,具体思路是:既然rand7()是随机的,那么rand7() + (rand7() + 7)即是rand14(),同理rand7() + (rand7() + 7 * 1) + (rand7() + 7 * 2)即是rand21(),依此类推可得rand70为
for(int i = 0; i < 10; i++){
sum += rand7() + i *……

[解决办法]
探讨

rand7() + (rand7() + 7 * 1) + (rand7() + 7 * 2)
= rand7() + rand7() + rand7() + 21;
这样你的方法跟 83,91楼的方法一样。至于为什么会被误认为是完全随机,那只是分布得比较均匀。在93楼,有我对所有情况的统计的程序。如果要运行它。请直接用release模式。

[解决办法]
android的资料嵌入式板块不是有分享吗,很多很强大的资料
[解决办法]
((rand7()-1)+(rand7()-1)*6+(rand7()-1)*36)%10+1
========================================
换个思维:
设rand9()生成0--9间的随机数,要求生成0--99间的随机数,即要求能生成个位0--9外还要生成十位的0--9.
方法是rand9()+rand9()*10
这样可以生成理论上连续的0--99间的随机数.

回到LZ问题上:rand7()本质上是生成6个随机数,问题是先要生成远远多于6个随机数(理论上连续),按上述十进制随机数的概念去生成两位六进制数(连续00--55),对应十进制数是0--35,mod10之后0--5的比率要大于6--9比率.不妨生成三位6进制数(连续000--555),对应十进制数是0--215,这样mod10后0--9的比率就大致差不多了
[解决办法]
有个出发点错误,应该是七进制,误以为是六进制了.将6改成7就可以了.

读书人网 >C++

热点推荐