C语言乐透抽奖代码如何通过数组校验已使用的随机数值?
乐透号码生成程序逻辑讲解
这是一个实现49选6乐透随机不重复号码生成的C语言程序,核心通过标记数组实现号码去重。
前置初始化逻辑
- 首先定义两个常量:
maxrange = 49代表可选号码范围是1~49,maxballs = 6代表需要抽取6个不重复号码 - 定义数组
int numbers[maxrange]作为使用状态标记数组:- 数组下标048分别对应号码149,也就是号码
b对应的数组下标是b-1 - 初始循环把数组所有元素赋值为
0,0代表对应号码未被抽取过,1代表对应号码已经被抽取过
- 数组下标048分别对应号码149,也就是号码
seedrnd()函数用当前系统时间初始化随机数种子,保证每次程序运行生成的随机序列都不一样
核心去重逻辑(你疑惑的校验部分)
首先说明原代码存在的小笔误:原代码中 for (i = 0; i < maxballs; i++); 末尾多了一个多余的分号,会导致外层循环空转6次,后续代码只执行1次,仅输出1个号码,删除该分号后功能正常。
正常逻辑下外层循环会执行6次,每次抽取1个有效号码,对应代码拆解:
// 循环6次,生成6个不重复号码 for (i = 0; i < maxballs; i++) { do { // 生成1~49之间的随机数 b = rnd(maxrange); // 检查该号码对应的标记位,如果为1说明已被使用,重新生成 } while (numbers[b - 1]); // 标记该号码为已使用 numbers[b - 1] = 1; // 打印有效号码 printf("%i ", b); }
逐步运行逻辑:
- 进入do-while循环,首先生成一个随机号码
b - 检查
numbers[b-1]的值:- 如果值为
1:说明号码b之前已经抽到过,while条件成立,重新进入do块生成新的随机数 - 如果值为
0:说明号码b未被使用,while条件不成立,跳出do-while循环
- 如果值为
- 把
numbers[b-1]设为1,标记这个号码后续不能再被使用 - 打印本次抽到的有效号码
举个实际运行示例:
- 第一次循环生成随机数
7,对应下标是6,numbers[6]初始是0,跳出循环,把numbers[6]设为1,打印7 - 第二次循环如果又生成了
7,检查numbers[6]是1,就会重新生成随机数,直到抽到未被标记的号码为止
通过这个机制就能保证最终输出的6个号码完全不重复。
辅助函数说明
rnd(int range):生成1range之间的随机整数,原理是`rand()`生成0RAND_MAX的随机数,对range取模得到0range-1的结果,加1后范围偏移到1rangeseedrnd(void):调用srand()用当前时间戳作为随机数种子,避免每次运行程序生成的号码都相同
内容的提问来源于stack exchange,提问作者ONees
相关产品推荐
相关产品推荐

