生成0-6无重复随机值数组及枚举数组的实现问题
解决0-6无重复随机数组生成问题,附枚举类型实现
我来帮你搞定这个问题!你的代码现在存在两个关键问题:一是只检查了当前随机数和前一个元素是否重复,完全没和更早的元素比对,所以会出现比如[2,5,2]这种跨位置的重复;二是rand() % 6只能生成0-5的数值,永远到不了6,这和你要的0-6范围不符。
一、修复无重复整数数组生成
这里给你两种可靠的实现方式:
方法1:生成后全量比对(适合小范围场景)
这种方法逻辑直观,生成随机数后和数组里已经存在的所有元素逐一比对,直到找到不重复的数值:
#include <stdlib.h> #include <stdbool.h> // code:存储结果的数组,size:需要生成的元素个数(最大7,因为0-6共7个不重复值) void randomArray(int code[], int size) { if (size > 7) { return; // 超出范围直接返回,也可以根据需求加错误处理 } for (int i = 0; i < size; i++) { int randNum; bool isDuplicate; do { randNum = rand() % 7; // 0-6共7个值,所以取模7 isDuplicate = false; // 和之前所有已生成的元素比对 for (int j = 0; j < i; j++) { if (code[j] == randNum) { isDuplicate = true; break; } } } while (isDuplicate); // 重复就重新生成 code[i] = randNum; } }
方法2:Fisher-Yates洗牌法(更高效)
如果需要生成的元素数量接近7个,洗牌法的效率更高——先创建一个0-6的有序数组,然后打乱顺序,再取前N个元素:
#include <stdlib.h> void shuffleArray(int code[], int size) { if (size > 7) { return; } // 先初始化0-6的完整序列 int temp[7]; for (int i = 0; i < 7; i++) { temp[i] = i; } // Fisher-Yates核心洗牌逻辑 for (int i = 6; i > 0; i--) { int j = rand() % (i + 1); // 生成0到i的随机索引 // 交换两个位置的元素 int swap = temp[i]; temp[i] = temp[j]; temp[j] = swap; } // 把前size个打乱后的元素存入目标数组 for (int i = 0; i < size; i++) { code[i] = temp[i]; } }
二、枚举类型数组的生成
生成枚举数组的思路和整数数组完全一致,只需要把整数转换成对应的枚举类型即可。假设我们定义了如下枚举:
typedef enum { Zero, One, Two, Three, Four, Five, Six } NumberEnum;
方法1:全量比对法
#include <stdlib.h> #include <stdbool.h> void randomEnumArray(NumberEnum code[], int size) { if (size > 7) { return; } for (int i = 0; i < size; i++) { NumberEnum randEnum; bool isDuplicate; do { // 把随机整数强制转换为枚举类型 randEnum = (NumberEnum)(rand() % 7); isDuplicate = false; for (int j = 0; j < i; j++) { if (code[j] == randEnum) { isDuplicate = true; break; } } } while (isDuplicate); code[i] = randEnum; } }
方法2:洗牌法
#include <stdlib.h> void shuffleEnumArray(NumberEnum code[], int size) { if (size > 7) { return; } // 初始化完整的枚举序列 NumberEnum temp[7] = {Zero, One, Two, Three, Four, Five, Six}; // Fisher-Yates洗牌 for (int i = 6; i > 0; i--) { int j = rand() % (i + 1); NumberEnum swap = temp[i]; temp[i] = temp[j]; temp[j] = swap; } // 取前size个元素 for (int i = 0; i < size; i++) { code[i] = temp[i]; } }
重要提醒
使用rand()之前,一定要在程序开头调用srand(time(NULL))初始化随机种子,否则每次运行程序生成的随机序列都会完全相同:
#include <time.h> int main() { srand(time(NULL)); // 初始化随机种子,只需要调用一次 int intCode[4]; randomArray(intCode, 4); NumberEnum enumCode[4]; randomEnumArray(enumCode, 4); // 后续逻辑 return 0; }
内容的提问来源于stack exchange,提问作者Facundo Schiavoni
相关产品推荐
相关产品推荐

