C语言生成含特殊符号随机二维数组 修复填充顺序与符号等量分布问题
问题修复说明
错误原因分析
- 填充顺序错误:原代码行遍历逻辑为
for(a = 0; a < y; a++),默认从数组第0行(视觉上的最顶部)开始填充输出,不符合从底部开始填充的要求。 - 符号等量分配逻辑完全错误:原代码采用「先随机赋值、后计数校验、超量就改空格」的逻辑,既无法保证
!@#$每个符号恰好出现y次,还会产生大量多余空白;同时计数时机错误,赋值后才修改计数变量,即使后续把值改成空格,计数也已经被污染,完全达不到统计效果。
修复方案
- 调整行遍历顺序:填充和输出时都从最后一行(索引为y-1,视觉上的最底部)倒序遍历到第0行,实现从底部开始填充的效果。
- 重构符号分配逻辑:
- 先初始化整个数组为空格,标记好2个固定全空的列。
- 预生成符号池:按需求向池中加入y个
!、y个@、y个#、y个$,将池内符号随机打乱。 - 遍历数组非空白列位置,依次填入打乱后的符号,天然保证每个符号出现次数恰好为y次,且位置随机。
修改后完整代码
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h> int main() { srand(time(NULL)); int y, x; y = rand() % 6 + 3; // 行数范围3~8 x = rand() % 5 + 4; // 列数范围4~8 char field[y][x]; // 初始化数组全为空格 memset(field, ' ', sizeof(field)); const char* symbol = "!@#$"; // 生成两个不重复的固定空白列 int blank_col1 = rand() % x; int blank_col2 = rand() % x; while (blank_col1 == blank_col2) { blank_col2 = rand() % x; } // 预生成符号池:四个符号各y个 int total_sym = 4 * y; char sym_pool[total_sym]; for (int i = 0; i < y; i++) { sym_pool[i*4] = '!'; sym_pool[i*4+1] = '@'; sym_pool[i*4+2] = '#'; sym_pool[i*4+3] = '$'; } // Fisher-Yates算法打乱符号池 for (int i = total_sym -1; i > 0; i--) { int j = rand() % (i+1); char temp = sym_pool[i]; sym_pool[i] = sym_pool[j]; sym_pool[j] = temp; } // 从底部开始填充符号,跳过空白列 int sym_idx = 0; for (int a = y-1; a >= 0; a--) { // 倒序遍历行,从最底部开始填充 for (int b = 0; b < x; b++) { if (b != blank_col1 && b != blank_col2 && sym_idx < total_sym) { field[a][b] = sym_pool[sym_idx++]; } } } // 输出数组,行号从1开始递增显示 for (int a = y-1; a >= 0; a--) { printf("\n %d |", y - a); for (int b = 0; b < x; b++) { printf(" %c |", field[a][b]); } } // 输出底部边框和列号 putchar('\n'); printf(" "); for (int b = 0; b < x; b++) { printf("--- "); } putchar('\n'); printf(" "); for (int b = 0; b < x; b++) { printf(" %d ", b+1); } putchar('\n'); return 0; }
内容的提问来源于stack exchange,提问作者Paul Atreides
相关产品推荐
相关产品推荐

