C语言生成含唯一1-6及60%概率0的数组时输出乱码问题
问题诊断与修复方案
核心错误原因
你遇到的乱码问题和malloc内存分配无关,是逻辑分支缺失导致的数组位置未初始化,存在三个明显错误:
- 0值分支逻辑不完整:当生成的随机数为0且不允许插入0时,既没有对当前数组位置赋值,也没有回退索引重新生成,直接进入下一轮循环,对应位置保留的就是内存中的原始垃圾值
- 概率判断逻辑错误:
rand()返回的是[0, RAND_MAX]范围的整数,直接和0.6比较等价于判断rand() == 0,实际允许0的概率远低于预期的60% - 缺少malloc失败校验:如果内存分配失败返回NULL,后续操作会触发段错误
修复后的实现代码
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define SIZE 6 int *t_size(){ int i, j; int *tab = (int*)malloc(sizeof(int) * SIZE); // 新增内存分配失败判断 if (tab == NULL) { return NULL; } int randnum; // 修正概率计算逻辑,实现60%允许插入0的效果 bool allow_zero = (double)rand() / RAND_MAX <= 0.6; for(i = 0; i < SIZE; i++){ randnum = rand() % (SIZE + 1); printf("%d \n", randnum); if(randnum == 0){ if (allow_zero){ tab[i] = randnum; continue; } else { // 不允许插入0时回退索引,重新生成随机数 i--; continue; } } // 非0值查重逻辑 for(j = 0; j < i; j++){ if(randnum == tab[j]) break; } if (i == j){ tab[i] = randnum; printf("tab [%d] val %d \n", i, tab[i]); } else { i--; } } return tab; }
算法优化建议
- 替换随机生成+查重的逻辑为洗牌算法:先生成存储1-6唯一值的数组,调用Fisher-Yates算法打乱顺序,再根据概率随机选择若干位置替换为0,时间复杂度从O(n²)降到O(n)
- 用长度为7的标记数组记录已出现的非0值,查重操作从遍历数组的O(n)复杂度降到O(1)
- 提前统计已填充的非0值数量,当6个非0值全部填充完毕后,后续剩余位置直接按规则赋值,避免无效循环
内容的提问来源于stack exchange,提问作者Zerch
相关产品推荐
相关产品推荐

