C_C++随机数据生成(is how to use but not how it work)

1.int rand(void)
库:stdlib.h
功能:随机数发生器,值在0至RAND_MAX之间,RAND_MAX定义在stdlib.h, 其值为2147483647
解释:首先不是真的随机数,只是周期比较长。然后如果不设置随机数种子默认是1.

2.void srand(unsigned int seed)
库:stdlib.h
功能:初始化随机数种子
解释:初始化种子,要不每次重新运行程序随机数是一样的。但是重新开始的时候种子仍然是原先设定,所以一般会和time()一起使用。

3.time_t time(time_t* t);
库:time.h
功能:取得从1970年1月1日至 t 的秒数
解释:time_t是long数据类型,前面用typedef重命名的。如果参数是空,默认是当前时间。


下面看具体使用:
1.最简单的生成随机数

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <time.h>

using namespace std;

int main()
{
    for(int i=0;i <10;++ i)
        printf("%d ",rand());
    return 0;
}

简单随机数生成

2.结合time设置随机数种子

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <time.h>

using namespace std;

int main()
{
    srand((unsigned int)time(NULL));

    for(int i=0;i <10;++ i)
        printf("%d ",rand());
    return 0;
}

每次不同的随机数
3.设定指定区域的随机数
思路:如果想得到[a,b]的随机数,等价于获得一个随机数n,将这个随机数和a相加,可以保证 a(rand的返回值[0,RAND_MAX]),接下来保证a+n bnba , rand()%(b-a)一定是一个[a,b)的整数(这里取不到b的原因是n的时候余0,所以n取不到)。
a+rand()%nx[a,a+n)
推广一下:
[a,b] a+rand()%(b-a+1)
(a,b] a+1+rand()%(b-a+1)
[a,b) a+rand()%(b-a)
(a,b) a+1+rand(b-a)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <time.h>

using namespace std;

int main()
{
    srand((unsigned int)time(NULL));

    int a = 0,b = 0;
    printf("input a ans b:\n");
    scanf("%d%d",&a,&b);
    printf("get random number which range is [%d,%d]:",a,b);
    for(int i=0; i <10; ++ i)
        printf("%d ",a+rand()%(b-a+1));
    return 0;
}

指定范围

4.推广一下负数
首先设想一下负数,自然想到上述范围公式,如果将负数代入会怎样?例如我们想要得到[-7,5]之间的随机数,结果如图:
负数
其实上面我们已经证明了范围取值的正确性,负数显然是整数也是符合上述的规则的。
很容易想到 [,+] ,或者包含 的情况。这里我只讨论第一种情况,后面的以后又想瞎搞的时候在搞吧。
对于上面的范围,直接想到RAND_MAX/2减去产生的随机数。但是现实很残酷,竟然没有超过一半的!!!不知道原因,这里主要是为了利用上述的思想,我还是想到了一个办法,用一个随机数-随机数。(或者利用计算机存储数值的特点进行二进制左移操作也能得到负数,但是这是简单问题复杂化了)

5.推广一下小数
很容易用分治的思想将产生一个小数分解成产生一个随机整数和[0,1)的小数问题。产生指定整数上面讨论过了,只要知道了[0,1)的随机小数怎么产生就行了。
我们知道rand()产生的是[0,RAND_MAX]的整数,那么我们直接将这个数除以RAND_MAX不就得到了所需的随机小数!
分治完成,归并就可以推广到指定小数了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值