我编写了一个程序,该程序创建一个包含随机字符串的字符串数组,rand_str()
的长度为20个字符串。当我使用sleep()
时,结果正是我想要的。但是,我认为sleep()
不应该出现在我的代码中。删除sleep()
,创建的随机字符串完全不同。我对此很困惑。有人可以帮忙解释为什么会这样吗?
#include <iostream>
#include <string.h>
#include <random>
#include <ctime>
#include <cstdlib>
#include <windows.h>
#include <stdlib.h>
#include <array>
#define show(w) for(auto val:w){cout<<val<< " ";}cout<<endl;
using namespace std;
char *rand_str(char *str,const int len);
int main(){
const int len = 10;
char *a[len];
string c[len];
array<string,len> ar;char b[len][21];
for (int i = 0; i < len; ++i) {
ar[i] = rand_str(b[i], 21);
fflush(stdin);
// Sleep(1000);
}
show(ar);
return 0;
}
char *rand_str(char *str,const int len){
srand(time(NULL));
int i;
for(i=0;i<len;++i)
{
switch((rand()%3))
{
case 1:
str[i]='A'+rand()%26;
break;
case 2:
str[i]='a'+rand()%26;
break;
default:
str[i]='0'+rand()%10;
break;
}
}
str[len - 1]='\0';
return str;
}
不使用sleep():
使用sleep():
答案 0 :(得分:3)
您编写的程序执行得足够快,以至于rand_str
的每个循环极有可能在一秒钟的时间内发生。这很重要,因为生成字符串的方法涉及对time
的调用,因为time
返回一个time_t
对象,该对象在C标准中指定为:
未指定time_t中的日历时间编码,但是大多数系统符合POSIX规范,并返回一个整数类型的值,该值保存了自大纪元以来的秒数。其中time_t是32位有符号整数的实现(许多历史实现)在2038年失败。
—
time
,C++ Reference
因此,如果整个程序在不到一秒的时间内执行,则在该范围内对time
的每次调用都将返回相同的值,并为您的随机数播种相同的值,并在每个循环中产生相同的输出。相反,Sleep
持续1000毫秒(1秒)时,您几乎可以保证每次执行都将具有不同的种子,因此输出也不同。
通常,在程序开始时,只应给随机数播种一次。另外,您应该考虑使用<random>
库,因为它包含了生成随机数更好的机制。
答案 1 :(得分:2)
rand_str
最有可能与时间相关。您提出的种子的 seed 设置为srand(time(NULL));
,所以确实如此。
Sleep(1000)
(至少睡眠1000个单位的 时间)足以更改结果。
删除睡眠调用和程序执行速度足够快,以至于无法观察到rand_str
的时间依赖性。
答案 2 :(得分:1)
您的rand_str
函数在每次调用时重新植入PRNG ,并使用以秒为单位的当前时间。然后,它将按该顺序拉出“第一个”数字并返回它。
这意味着对于不同时间的函数调用,您只会获得不同的伪随机序列。如果在同一秒内进行多个函数调用,则使用相同的种子继续进行重新播种,这将导致相同的序列,并且相同序列中的第一个数字始终是相同的数字。这就是为什么睡眠有所作为:它改变了种子。
您应该先only seed once, at the start of your program,然后根据需要use the resulting sequence。
顺便说一下,整个方法论已经过时了。从C ++ 11开始,we do random numbers like this。
答案 3 :(得分:-1)
这很可能是由于计算机无法产生真正的随机数。
因此,存在称为seed
的概念。伪随机数生成最常见的seed
是时间。
让您的程序稍等一下,将使其以其他种子运行随机生成器。