C语言从数组无重复选取随机字符存入另一数组问题求助
现有代码存在的问题
- 未初始化的数组调用
strlen计算长度:array定义后未赋值填充'\0'结束符,strlen(array)返回的是随机值,该行代码无实际作用且逻辑错误。 - 随机下标范围错误:原字符数组
characters共有9个有效元素,rand() % 4只能生成03的下标,仅能取到前4个字符AD,本身就缩小了候选字符范围。 - 去重逻辑完全无效:内层循环中检测到重复时,仅将已经生成的重复值重新赋值给
array[i],没有重新生成新的随机字符,等于没有处理重复;且循环范围j < 4会读取array中还未赋值的垃圾值进行无意义比较,同时j=i时必然判定相等,逻辑完全错误。 - 数组未初始化:
array未做初始化,未使用的位置存储的是随机脏数据,可能引发未定义行为。
正确实现方案
这里提供两种常用的实现思路,你可以按需选择:
方案1:标记法实现无重复选取
思路:每次生成随机下标后,检查该下标对应的字符是否已经被选取过,未被选取则存入目标数组,直到选够指定数量的字符。
代码示例:
#include <stdio.h> #include <stdlib.h> #include <time.h> int main() { srand(time(NULL)); char characters[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I' }; int char_cnt = sizeof(characters) / sizeof(characters[0]); // 计算原数组元素总数 char result[4]; // 要存4个无重复字符 int used[9] = {0}; // 标记原数组对应下标是否被使用,初始全为0未使用 int selected_cnt = 0; while (selected_cnt < 4) { int rand_idx = rand() % char_cnt; // 生成0~8的合法随机下标 if (!used[rand_idx]) { // 该下标未被使用过 result[selected_cnt] = characters[rand_idx]; used[rand_idx] = 1; // 标记为已使用 selected_cnt++; } } // 输出结果 for (int i = 0; i < 4; i++) { printf("%c ", result[i]); } return 0; }
方案2:洗牌法实现无重复选取
思路:将原字符数组随机打乱顺序,直接取前4个元素即可,无需额外标记,适合候选集不大的场景,效率更高。
代码示例:
#include <stdio.h> #include <stdlib.h> #include <time.h> int main() { srand(time(NULL)); char characters[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I' }; int char_cnt = sizeof(characters) / sizeof(characters[0]); char result[4]; // 洗牌:遍历数组,每个位置和随机位置交换 for (int i = char_cnt - 1; i > 0; i--) { int rand_idx = rand() % (i + 1); char temp = characters[i]; characters[i] = characters[rand_idx]; characters[rand_idx] = temp; } // 直接取前4个元素 for (int i = 0; i < 4; i++) { result[i] = characters[i]; printf("%c ", result[i]); } return 0; }
内容的提问来源于stack exchange,提问作者david
相关产品推荐
相关产品推荐

