网站首页 > 技术文章 正文
在C语言中,rand()函数用于生成随机数,但其生成的序列是可预测的,因为默认情况下rand()函数使用的是固定的种子。为了使生成的随机数序列在每次运行程序时不同,必须使用srand()函数来初始化随机数生成器的种子。通常,我们会使用当前时间作为种子,这样可以保证每次运行程序时生成不同的随机数序列。
1.避免在同一时间内多次初始化种子
一个常见的错误是,在短时间内多次调用srand(time(0))进行种子初始化。由于time(0)返回的是当前时间的秒数,如果在同一秒内多次调用srand(time(0)),就会导致多次初始化使用相同的种子,从而生成相同的随机数序列。为了避免这个问题,我们应该在程序开始时只调用一次srand()进行种子初始化。
实例1 生成连续随机数
程序
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int num = 0;
time_t now_time;
now_time = time(NULL);/*获取当前时间的秒数*/
srand((unsigned) now_time);/*根据时间生成种子*/
/*生成0-520之前的随机数*/
/*设范围区间为(max,min),那么只需 rand%(max-min+1)+min 即可*/
num = rand()%(520-0+1)+0;/*注意521会被整除*/
printf("生成0-520之前的随机数:%d\n",num);
/*连续生成随机数*/
int i;
for(i = 0;i < 10; i++)
{
srand((unsigned) now_time);/*根据时间生成种子*/
num = rand();
printf("%d ",num);
}
/*for 循环运行速度非常快,在一秒之内就运行完成了,而 time() 函数得到的时间只能精确到秒,所以每
次循环得到的时间都是一样的,这样一来,种子也就是一样的,随机数也就一样了。*/
getchar();
return 0;
}
运行结果
实例2 只初始化一次srand函数
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int num = 0;
time_t now_time;
now_time = time(NULL);/*获取当前时间的秒数*/
srand((unsigned) now_time);/*根据时间生成种子*/
/*连续生成随机数*/
int i;
for(i = 0;i < 10; i++)
{
num = rand();
printf("%d ",num);
}
getchar();
return 0;
}
运行结果
2.以随机数加时间做种
程序
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int num = 0;
time_t now_time;
now_time = time(NULL);/*获取当前时间的秒数*/
/*连续生成随机数*/
int i;
for(i = 0;i < 10; i++)
{
srand((unsigned) now_time + (unsigned)rand());/*根据时间和随机数生成种子*/
num = rand();
printf("%d ",num);
}
getchar();
return 0;
}
运行结果
3.网上的其他方法
程序
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
//准备
int a, b, c, d;
int rand_var;
int *number;
char *used;
clock_t c_t;
srand(1);
printf("请输入生成随机数的范围(a~b):");
scanf_s("%d~%d", &a, &b);
if (a > b)
return 0;
number = (int*)malloc(sizeof(int)*(b - a + 1));
/*
方法1:
先初始化number数组,每个元素的值都为一个不在范围内的数(此处a-1必然是不在范围内的数)
抽取随机数,如果number[随机数]是a-1,则录入一次c的值,并++c,否则c不变,重新抽取随机数
*/
c_t = clock();
for (c = a; c <= b; ++c)
number[c - a] = a - 1;
for (c = a; c <= b; ++c) {
rand_var = rand() % (b - a+1);
if (number[rand_var] == a - 1)
number[rand_var] = c;
else
--c;
}
c_t = clock() - c_t;
printf("第一种生成方法花费时间:%dms\n", c_t);
printf("第一种方法:");
for (c = a; c <= b; ++c)
printf("%d ", number[c - a]);
printf("\n");
/*
方法2:
抽取随机数,并且与之前抽取过的数进行遍历比较,若不同则录入,否则重新抽取
*/
c_t = clock();
for (c = a; c <= b; ++c) {
rand_var = rand() % (b - a + 1) + a;
for (d = a; d < c; ++d)
if (number[d - a] == rand_var)
break;
if (d == c)
number[c - a] = rand_var;
else
--c;
}
c_t = clock() - c_t;
printf("第二种生成方法花费时间:%dms\n", c_t);
printf("第二种方法:");
for (c = a; c <= b; ++c)
printf("%d ", number[c - a]);
printf("\n");
/*
方法3:
准备一个额外的used数组,并初始化0
抽取随机数,如果used[随机数]为0,则录入该随机数进number,否则重新抽取随机数
*/
c_t = clock();
used = (char*)malloc(sizeof(char)*(b - a + 1));
for (c = a; c <= b; ++c)
used[c - a] = 0;
for (c = a; c <= b; ++c) {
rand_var = rand() % (b - a + 1);
if (used[rand_var])
--c;
else {
used[rand_var] = 1;
number[c - a] = rand_var + a;
}
}
free(used);
c_t = clock() - c_t;
printf("第三种生成方法花费时间:%dms\n", c_t);
printf("第三种方法:");
for (c = a; c <= b; ++c)
printf("%d ", number[c - a]);
printf("\n");
/*
方法4:
先初始化number数组,每个元素从a到b已经顺序排列完成
抽取随机数作为下标,从而进行随机换位从而达到目的
*/
c_t = clock();
for (c = a; c <= b; ++c)
number[c - a] = c;
for (c = a; c <= b; ++c) {
rand_var=rand() % (c - a + 1);
if (rand_var != c - a) {
number[c - a] ^= number[rand_var];
number[rand_var] ^= number[c - a];
number[c - a] ^= number[rand_var];
}
}
c_t = clock() - c_t;
printf("第四种生成方法花费时间:%dms\n", c_t);
printf("第四种方法:");
for (c = a; c <= b; ++c)
printf("%d ", number[c - a]);
printf("\n");
free(number);
return 0;
}
运行结果
参考内容
[1] c语言如何多次随机数 | PingCode智库,文章网址https://docs.pingcode.com/baike/1221453
[2] [C]生成指定范围内不重复元素的随机数数列的四种方法_c语言生成不重复的随机数
https://blog.csdn.net/qq_43655831/article/details/108245306
[3] 【C语言】连续生成多个随机数_c语言连续生成多个随机数-
https://blog.csdn.net/dakaidada/article/details/122431074
[4] C语言随机数生成方法——srand种子的讨论
https://blog.csdn.net/Tangramor/article/details/11808997
本文内容来源于网络,仅供参考学习,如内容、图片有任何版权问题,请联系处理,24小时内删除。
作 者 | 郭志龙
编 辑 | 郭志龙
校 对 | 郭志龙
- 上一篇: C++20尝鲜:新增语法糖
- 下一篇: “Rust真能防住C代码里的那些老问题吗?我们做了个实验验证”
猜你喜欢
- 2025-05-14 “Rust真能防住C代码里的那些老问题吗?我们做了个实验验证”
- 2025-05-14 C++20尝鲜:新增语法糖
- 2025-05-14 C 语言的整数提升
- 2025-05-14 C语言之位运算符
- 2025-05-14 CSP-J 2024 信奥赛入门组第一轮初赛真题及答案解析(C++)
- 2025-05-14 C/C++快速排序
- 2025-05-14 C语言基础练习10-条件运算符实现成绩等级
- 2025-05-14 单片机C语言基础分享,变量声明与数据类型
- 2025-05-14 C C++ 中自定义可变参数函数调用其它可变参数函数
- 2025-05-14 C语言实战之Excel表列序号
- 最近发表
- 标签列表
-
- cmd/c (64)
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- sqlset (64)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- js数组插入 (83)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)