一、 假如要生成一个包含包含9个元素的一维数组,元素分别是1到9这9个整数随机排列,每个数字都出现一次。 产生思路为: 1.产生一个全0的数组A 2.产生一个1到9之间的随机数a 3.将a放到A中 4.继续产生随机数,并判断a是否存在于A中 5.若在则跳过,不在则放入A中 6.9个数字都填完以后结束 运行程序如下`
#include <iostream>
int main()
{
int num[9] = { 0 };
int i = 0;
while (num[8] == 0)
{
srand((int)time(0));
int a = (rand() % 9) + 1;
int start = 0;
int end = 8;
int* result = find(num + start, num + end, a);
if (result == num + end)
{
num[i] = a;
i++;
}
}
for (int i = 0; i < 9; i++)
cout << num[i] << ' ';
return 0;
}
运行结果如图所示: 结果显示正确 二、 上面写的程序在实际运行时,产生一个数组要花费十秒左右的时间,如果想要快速产生大量数组,比如成百上千个,这段程序就不适用了。 主要原因就出在下面这两行
srand((int)time(0));
int a = (rand() % 9) + 1;
C++产生随机数是通过rand函数计算得到的,是一种伪随机数,开始计算时需要一个随机种子,当随机种子相同时,得到的随机数也是一样的。所以想得到不同的随机数就要设置不同的随机种子。 srand函数就是设置随机种子的,time(0)的返回值是从1970年1月1日至今所经历的时间(以秒为单位),转换整形后由srand((int)time(0))作为了随机种子,可以保证随机种子的不同。 常见产生随机数的方式,都是用当前时间作为随机种子的,这样做比较简单。但问题就在于产生不同随机种子的时间至少要间隔一秒,当需要产生大量随机数时就会导致时间的增加。所以此时并不适用直接将时间作为随机种子。 改进程序如下:
int main()
{
for (int i = 0; i < 9; i++)
{
int k = (int)time(0);
int num[9] = { 0 };
int m = 0;
int j = 50 * (i * i * i + 100 + i * i * 5 - 20)+k;
\\这个有关i的表达式是我随便写的,每个人都可以写自己的,只要让当i不同时计算结果差距较大就可以
\\由于每次得到的i不同,与k结合以后的j就都不会相同
while (num[8] == 0)
{
srand(j);
int a = (rand() % 9) + 1;
int start = 0;
int end = 8;
int* result = find(num + start, num + end, a);
if (result == num + end)
{
num[m] = a;
m++;
}
j++;
}
for (int i1 = 0; i1 < 9; i1++)
{
cout << num[i1];
}
cout << endl;
}
return 0;
}
运行结果如图: 运行结果正确,并且运行时间不到一秒钟。
三、 这段程序同样还有缺点,我在实测产生一百个数组时,发现产生速度虽然韩快,但偶尔会出现两个相邻数组一模一样的情况。我认为还是随机种子的设置不够好,没办法做到完全随机。如果是生成9个数组,没有发现过出现一样的数组。
四、 使用rand产生随机数的公式如下: 要取得[0,n) 就是rand()%n 表示 从0到n-1的数 要取得[a,b)的随机整数,使用(rand() % (b-a))+ a; 要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a; 要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1; 通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。 要取得a到b之间的随机整数,另一种表示:a + (int)b * rand() / (RAND_MAX + 1)。 要取得0~1之间的浮点数,可以使用rand() / double(RAND_MAX)。
|