从字符串选字符填充二维数组遇问题,求技术指导
二维数组填充问题求助
我尝试从字符串中选取特定字符填充二维数组,要求满足以下条件:
- 保留2个相邻的空列
- 每个字符的出现次数与行数(rows)相等(类似小球排序游戏的布局)
但当前代码无法实现预期效果,附上代码和预期效果说明,求解决建议。
预期效果:类似小球排序的布局,每列(非空列)由相同字符堆叠,每个字符恰好占据rows个位置,同时存在两个相邻的全空列。
当前代码
void generator(const int rows, const int columns, char field[rows][columns]){ // seed srand(time(NULL)); int random_index; // choosing empty columns (they'll be by side) int clear_column[2]; // choosing random number in range of columns clear_column[0] = rand() % (columns+1); // adding +1 index to already choosen number clear_column[1] = clear_column[0]+1; // if choosen number is equal to number of columns => second empty column will be on the left side if ( clear_column[0] == columns) { clear_column[1] = clear_column[0]-1; } // variable to store all symbols char store_symbol[10] = "^@#&*+-/$"; // variable to store used symbols int store_index[10] = {0,0,0,0,0,0,0,0,0}; // ** i = columns; k = rows // loops all columns for (int i = 0; i < columns; i++) { // loops all rows for (int k = 0; k < rows; k++) { // adding empty columns if ( i == clear_column[0] || i == clear_column[1]) { field[k][i] = ' '; } else{ int got_symbol = 0; while (got_symbol == 0) { random_index = rand() % rows; if ( store_index[random_index] <= rows) { field[i][k] = store_symbol[random_index]; store_index[random_index] += 1; got_symbol = 1; break; } } } } } }
问题分析与修复建议
核心问题点
- 空列索引越界:原代码中
clear_column[0] = rand() % (columns+1)会生成0到columns的索引,而二维数组列索引范围是0到columns-1,导致空列位置可能超出数组边界。 - 数组索引颠倒:原代码中
field[i][k]把列索引放在行的位置,应该是field[k][i](行在前,列在后),这会导致字符填充位置完全混乱。 - 字符分配逻辑错误:随机选择字符并计数的方式无法保证每个字符恰好出现rows次,且容易出现同一列混合多个字符的情况,不符合小球排序的列一致性要求。
- 符号数组长度不足:
store_symbol定义为10个元素,但实际只有9个有效符号,若非空列数超过9会出现问题。
修复后的代码
#include <stdio.h> #include <stdlib.h> #include <time.h> void generator(const int rows, const int columns, char field[rows][columns]){ // 初始化随机种子 srand(time(NULL)); // 选择相邻的两个空列,确保索引在有效范围内 int clear_column[2]; clear_column[0] = rand() % (columns - 1); // 生成0到columns-2的随机数,避免第二列越界 clear_column[1] = clear_column[0] + 1; // 可用符号列表(保证数量 >= 非空列数columns-2) char store_symbol[] = "^@#&*+-/$%"; int total_symbols = sizeof(store_symbol) / sizeof(store_symbol[0]) - 1; // 排除末尾的空字符 // 标记已使用的符号,避免重复分配 int used_symbols[10] = {0}; // 遍历每一列 for (int col = 0; col < columns; col++) { // 处理空列:填充空格 if (col == clear_column[0] || col == clear_column[1]) { for (int row = 0; row < rows; row++) { field[row][col] = ' '; } continue; } // 为当前列分配一个未使用的随机符号 int sym_idx; do { sym_idx = rand() % total_symbols; } while (used_symbols[sym_idx]); used_symbols[sym_idx] = 1; // 填充整列的所有行,确保同一列字符一致 for (int row = 0; row < rows; row++) { field[row][col] = store_symbol[sym_idx]; } } } // 测试示例 int main() { int rows = 5; int columns = 7; char field[rows][columns]; generator(rows, columns, field); // 打印结果 for (int row = 0; row < rows; row++) { for (int col = 0; col < columns; col++) { printf("%c ", field[row][col]); } printf("\n"); } return 0; }
修复逻辑说明
- 空列生成:限制随机数范围为0到columns-2,确保两个相邻空列都在有效索引内
- 字符分配:为每个非空列分配唯一随机符号,保证每个符号恰好出现rows次(对应一列的所有行)
- 索引修正:使用
field[row][col]的正确顺序填充数组 - 符号唯一性:通过标记数组避免重复使用符号,确保布局符合小球排序的列特性
内容的提问来源于stack exchange,提问作者Samuel Vilkovský
相关产品推荐
相关产品推荐

