摘要:文章对随机数的应用问题进行了详细的分析, 给出了一种实现的算法, 并用C 语言实现。通过该问题的C 实现, 可使学习者
清晰地观测到解决该问题的全过程。
关键词:随机数; 算法; 随机排序
1 随机数产生的方法
在编程过程中,随机数有其广泛的应用价值。在C 语言中,可以利用C 语言中的种子函数srand()和伪随机函数rand()来实现。生
成步骤如下:
1) 首先给srand()提供一个种子,它是一个unsigned int 类型,其取值范围从0~65535;
2) 然后调用rand(),它会根据提供给srand()的种子值返回一个随机数(在0 到32767 之间);
3) 根据需要多次调用rand(),从而不间断地得到新的随机数;
4) 无论什么时候,都可以给srand()提供一个新的种子,从而进一步“随机化”rand()的输出结果。
范例源程序如下:
#include <stdlib.h>
void main()
{
int i;
srand((unsigned)time(NULL));
i = rand();
Printf("%d",i);
}
2 实际应用
在c 语言中,随机数的产生大致可以分为以下三种情况:
1) n 个任意的随机数的产生;
2) 从n 至n+m 的m+1 个随机数的产生;
3) 从n 至n+m 互不相同的m+1 个随机数产生。
前两种实现比较简单,在现实生活中应用较少。第三种实现较为复杂,较有实用价值,比如彩票选号,随机排列等。
下面以为随机为10 个学生分配1-10 十个座号为例说明。
3 算法分析
程序中学生对象必须有姓名和座号两个属性,不妨利用结构体来实现。生成座号方法有两种。
先说第一种。实现步骤如下:
第一步:在结构体初始化时直接指定学生姓名,座号可暂定为0。
第二步:利用随机函数生成学生座号,但生成的数值可能有重复。
第三步:利用循环语句生成新的座号,每生成一个新的座号,均需和以前的座号比较,若有重复,则重新生成,直到生成数值和前面所有数值均不相同。
这个算法在座号先生成后判断。生成后立刻作比较,如重复则重新生成。因此,在逐个生成之后即达到了预期目标。这种事算
法比较符合人们的逻辑,但需要重复比较,效率较低。
下面说第二种。实现步骤如下:
第一步:在结构体初始化时直接指定学生姓名、座号,座号可暂定为0。
第二步:定义一个一维数组a[10]存放1-10 十个座号,且令a[i]=i+1。
第三步:利用循环语句随机生成a 数组的第某个元素,如果该元素不等于0,则成为学生的座号。
第四步:a 数组的第某个元素归零,重新利用循环和判断生成下一个座号。
第二种算法是先判断后生成。思路为先生成一个放置座号的数组,然后从中随机抽取,抽取后为防止重复,立即归零。与第一种
算法相比,每次生成座号,只需判断是否为0 即可,大大提高了程序执行的效率。
4 C 语言实现
4.1 先生成后判断的程序实现
4.1.1 说明
1) 10 个学生姓名分别为:A,B,C,D,E,F,G,H,I,J。
2) 10 个学生的初始座号均为0。
3) 利用strand()函数和rand()函数产生随机数。
4.1.2 编程
#include <stdlib.h>
struct student
{
char name[10];
int num;
}
stu[10]={"A",0,"B",0,"C",0,"D",0,"E",0,"F",0,"G",0,"H",0,"I",0,"J",0};/* 初始化学生信息*/
main()
{
int i,j;
srand(time(0));
for(i=0;i<10;i++)
{
stu[i].num=rand()%10+1;
for(j=0;j<i;j++)
{
if(i! =0&&stu[i].num==stu[j].num)
{
stu[i].num=rand()%10+1;
j=-1;
}/* 重新产生座号*/
}
}
for(i=0;i<10;i++)
printf("\n%s:%d\n",stu[i].name,stu[i].num);/* 输出结果*/
}
4.2 先判断后生成的程序实现
4.2.1 说明
1) 10 个学生姓名分别为:A,B,C,D,E,F,G,H,I,J;初始座号均为0。
2) a 数组中存放座号。
3) 利用strand()函数和rand()函数随机抽取a 数组的第index 个元素。
4) 防止座号重复,a 数组的第index 个元素用完后立刻归零。
4.2.2 编程
#include <stdlib.h>
struct student {
char name[10];
int num;
}
stu[10]={"A",0,"B",0,"C",0,"D",0,"E",0,"F",0,"G",0,"H",0,"I",0,"J",0};
main()
{
int a[10],i,index,x=0;
for(i=0;i<10;i++)
a[i]=i+1; /* 存放座号*/
srand(time(0));
for(i=0;i<10;)
{
index=rand()%10; /* 随机抽取座号*/
if(a[index]! =0)
{
stu[i].num=a[index];
a[index]=0;
++i;
}
}
for(i=0;i<10;i++)
printf("\n%s:%d\n",stu[i].name,stu[i].num);
}
5 总结
C 语言产生互不相同的随机数,主要有两种方式,一种是先生成再判断,一种是先判断再生成。需要注意的是:前者要在判断过
程中要逐一比较,不可遗漏。程序中的j=-1 和循环中的j++相结合,正好从stu[0].num 开始比较。后者要先建立一个数组来存放座
号,然后才能随机抽取。