C++产生随机数一直重复的问题

C++产生随机数,我们都知道,无非就是利用srand产生一个种子,然后利用rand函数产生随机数即可。但是今天在产生随机数的时候遇到了一个怪事,就是不管自己怎么产搞,多次产生的随机数都是重复的。自己的代码简化为下:

#include "stdafx.h"
#include <cstdlib>
#include <ctime>
#include <iostream>

class  RandomNum
{
public:
	void creataRandomNum()
	{
		srand(unsigned(time(NULL)));
		std::cout << rand()<< std::endl;
	}
};

int main()
{
    for (int i=0;i<5;i++)
    {
		RandomNum random_num;
		random_num.creataRandomNum();
    }
}

很简单,就是在一个类中,有一个函数,在这个函数中产生随机数然后输出,来看一下输出的结果:

对的,你没看错,虽然设置了种子,但是输出的随机数是唯一的(不设置种子输出的随机数也是唯一的,有兴趣的话可以试一试)。

我们知道,srand()用来设置rand()产生随机数时的随机数种子。在调用rand()函数产生随机数前,必须先利用srand()设好随机数种子(seed), 如果未设随机数种子, rand()在调用时会自动设随机数种子为1(这也就是当我们不设置种子时,每次程序运行都会产生同样的随机数的原因)。进一步分析,我们在类里面调用产生随机数的函数以及设置种子的函数,那只要你的电脑足够好,程序运行的足够快,循环的每次(或者准确的说是前几次)每次srand()函数中获取的系统时间都是一致的,那么执行每次rand函数之前,设置的种子都一样,就和没设置种子一样了,这样导致了产生的随机数就是一样的。

那解决办法其实很简单,就是不要将srand函数放在类的函数内部,最好把它放在主函数中,这样就相当于设置了一次种子,但是产生了多次随机数。而不是像上面的代码一样,每次设置一次种子,产生一次随机数,然后设置的种子还一样,产生的随机数当然一样了。

修改后的代码如下:

#include "stdafx.h"
#include <cstdlib>
#include <ctime>
#include <iostream>

class  RandomNum
{
public:
	void creataRandomNum()
	{
		std::cout << rand()<< std::endl;
	}
};

int main()
{
	srand(unsigned(time(NULL)));
    for (int i=0;i<5;i++)
    {
		RandomNum random_num;
		random_num.creataRandomNum();
    }
}

看结果,产生的随机数已经正常了。

当然,在C++11中,已经有产生随机数的函数random,用法如下:

#include "stdafx.h"
#include <iostream>
#include <random>

int main()
{
	std::default_random_engine e;
	for (size_t i = 0; i < 5; ++i) //生成五个随机数       
		std::cout << e() << std::endl;
	std::cout << "Min random:" << e.min() << std::endl; //输出该随机数引擎序列的范围       
	std::cout << "Max random:" << e.max() << std::endl;
	return 0;
}

这种方式产生的随机数更好,如果能用这种方式的话,就尽量使用这种吧。

  • 33
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MeteorChenBo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值