C语言实现数组1-10随机数降序排列异常排查
问题现象
需求为生成取值范围1~10的随机数存入长度为7的数组,要求元素不重复、按降序排列后打印。实际运行时偶尔出现数字10排在数组末尾的异常,其余数字排序表现正常。
问题复现代码如下:
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { int a[7], j, i; srand(time(NULL)); a[0] = rand() % 10; int length = 7; for(int i = 0; i < 7; i++) { int duplikat = 0; a[i] = rand() % 10+1; for (int j=0; j<i; j++) { // descending order: Just change (a[j] > a[j+1]) if(a[i] == a[j]) duplikat = 1; if (a[j] < a[j+1]) { int temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } if (duplikat) i--; } } for(int i = 0; i< length; i++) { printf("a[%d] = %d\n", i, a[i]); } printf("\n"); for(j=0;j<7;j++) printf("\n%d ", a[j]); return 0; }
问题根因
- 生成随机数、去重、排序三个逻辑耦合在嵌套循环中,排序逻辑边界错误:内层循环遍历范围为
j < i,相邻交换仅能覆盖到下标i-1和i的位置,当新插入的元素为10时,单轮相邻交换无法将其移动到数组头部,后续循环不会再回溯处理前面的元素顺序,最终导致10滞留在数组末尾。 - 重复值处理逻辑位置错误:检测到重复值后在内层j循环中直接执行
i--,会打断当前轮次的排序流程,破坏已有的数组排序结果。 - 存在冗余无效代码:开头单独给
a[0]赋值的语句会被后续i=0轮次的赋值操作覆盖,且该行使用rand()%10生成的是09范围的值,不符合110的取值要求。 - 排序逻辑不完整:仅在插入新元素时做单次相邻遍历,没有实现完整的排序遍历流程,无法保证大值完全移动到对应位置。
修复方案
将随机数生成、去重、排序三个逻辑拆分,先生成符合要求的无重复随机数组,再单独执行完整的降序排序,避免逻辑耦合导致的边界错误,修复后代码如下:
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { int a[7]; srand(time(NULL)); int length = 7; // 生成7个1~10范围内的不重复随机数 for(int i = 0; i < length; i++) { int is_duplicate = 0; int num = rand() % 10 + 1; // 校验重复值 for (int j = 0; j < i; j++) { if (a[j] == num) { is_duplicate = 1; break; } } if (is_duplicate) { i--; // 重复则重新生成当前位置元素 continue; } a[i] = num; } // 单独执行降序冒泡排序 for(int i = 0; i < length - 1; i++) { for (int j = 0; j < length - 1 - i; j++) { if (a[j] < a[j+1]) { int temp = a[j]; a[j] = a[j+1]; a[j+1] = temp; } } } // 打印输出结果 for(int i = 0; i < length; i++) { printf("a[%d] = %d\n", i, a[i]); } return 0; }
内容的提问来源于stack exchange,提问作者Mervan
相关产品推荐
相关产品推荐

