C语言,一个彩票摇奖程序摇出22选5的中奖号码
2013-11-05 15:50 kingshow 阅读(2278) 评论(0) 编辑 收藏 举报摇奖机摇奖,无非就是利用它的随机性,让球从摇奖机中随机地掉出,就成了中奖号码。而C语言中也同样有个rand()函数可以产生随机数,利用这个rand()函数产生的随机数,同样可以代替从摇奖机中随机摇出的中奖号码。
然而,我们无法直接使用rand()函数来产生中奖号码,因为rand()产生的随机数字有一定的重复性,也就是rand()也许可以产生两个1,三个2,这显然不符合彩票的规则。那么,如何让rand()产生不重复的随机数字呢?
我们可以回想一下摇奖机是如何工作的:从容器中随机地摇出一个球,然后再从设个拿下的号码球中摇出第二个球。。。以此类推。而在C语言程序中,我们要想产生不重复的随机数字,也可以模仿这个过程来产生随机数字。首先在一个数组balls中保存所有的彩球号码(从1到22),然后,用rand()产生一个数组中号码个数范围内的随机数n(产生一个0到21范围内的随机数),然后用这个数n作为数组下标,从balls数组中取出的数字balls[n]就是摇出的号码,然后复制保存到中奖号码数组winnings中(winning[i]=balls[n]),因为一个号码已经被摇出了,所以我们将末尾的号码复制到已经被摇出的号码的位置(balls[n] = balls[M-i];),这样,这个数组中前面部分的号码依然是有效的,这是可以开始摇第二个球,用rand()产生一个0到20范围的随机数,得到第二个号码,以此类推,我们就可以得到五个随机的不重复的中奖号码了。
根据上面的分析,我们将这个摇奖程序实现如下:
// shuffle.c 福彩摇奖程序 // 中原风采22选5游戏规则 // 中原风采22选5属于低难度乐透型彩票, // 彩民只需从01至22个号码中任意选出5个号 // 码就可以组成一注。开奖后将投注号码与中 // 奖号码对照,没有特别号码,不排顺序和位置。 #include <stdio.h> #include <stdlib.h> // 引入rand(),srand()函数所在头文件 #include <time.h> const int M = 22; // 号码总数 const int N = 5; // 摇出的号码数 // 将22个号码装入摇奖机 void init(char* balls ) { for(int i=0;i<M;++i) { balls[i] = i + 1; } } // 摇奖,将中奖号码摇出到winnings数组 v void shuffle(char* balls,char* winnings) { // 用当前时间初始化随机种子 srand(time(NULL)); // 依次摇出N个中奖号码 for(int i = 0; i < N; ++i) { // 得到一个0到(M-i)之间的随机数 int n = rand()%(M - i); // 将摇出的号码复制到winnings保存 winnings[i] = balls[n]; // 用balls末尾的数字填补摇出号码的空位 balls[n] = balls[M-i]; } } int main(void) { // 准备摇奖 char balls[M]; init(balls); // 摇啊摇,摇啊摇 char winnings[N]; shuffle(balls,winnings); // 公布中奖号码,可惜中奖的不是我 puts("winning numbers:"); for(int i = 0; i < N; ++i) { printf("%d ",winnings[i]); } return 0; }
这里大家可能还有个疑问:这种方法,真的能够保证每个号码出现的几率都是一样的吗?比如,我们以数字1为例,1第一次就被摇出的几率,很明显是1/22,假如1第一次没被摇出,那么他第一次不被摇出的几率就是21/22,而这是只剩下了21个球,他第二次别摇出的几率就是1/21?啊,1/21不是比1/22高?几率不均等啊。且慢,虽然1第二次摇出的几率要高,但是这是在第一次不被摇出的基础之上的,所以他实际上第二次被摇出的几率是,(21/22)*(1/21)=1/22,依然是1/22,两次的几率实际上是一样的。