螺旋填充二维数组[N][M]的代码修复请求:适配任意整数维度(含奇数)
Fixing Odd-Dimensional Spiral Array Filling in C++
我看了你的代码,问题出在两个核心点:一是当N或M为奇数时,原循环只处理了完整的外层环,中间剩下的单行或单列完全没填充;二是circle函数里的索引计算和nums的增减逻辑有小漏洞,导致奇数维度时填充顺序混乱。咱们在严格保留你现有代码结构(宏定义、全局数组、函数拆分)的基础上修改:
问题根源拆解
- 原循环只运行
M/2或N/2次,比如N=5(奇数)时,N/2是2,处理完两层环后,中间第3行(索引2)完全是空的; circle里的N-N+k写法冗余且容易混淆,nums--的时机不对,导致某些位置重复赋值;p变量的递增逻辑在奇数维度时,会让右到左、下到上的循环范围出错。
修改后的完整代码
#include <iostream> #define N 5 // 可任意修改测试:奇数/偶数都支持,比如3、6 #define M 3 // 比如4、5 int nums = 1; int arr[N][M]; using namespace std; void printArr(){ for (int i = 0; i < N; i++){ for (int j = 0; j < M; j++){ cout << arr[i][j] << "\t"; } cout << endl; } } void circle (int k){ // 左到右:当前环的顶部行,从左边界到右边界 for (int i = k; i < M - k; i++){ arr[k][i] = nums++; } // 上到下:当前环的右侧列,从顶部行的下一行到底部行(避免重复覆盖) for (int i = k + 1; i < N - k; i++){ arr[i][M - 1 - k] = nums++; } // 右到左:当前环的底部行,仅当顶部行≠底部行时执行(防止单行重复填充) if (k != N - 1 - k) { for (int i = M - 2 - k; i >= k; i--){ arr[N - 1 - k][i] = nums++; } } // 下到上:当前环的左侧列,仅当左边界≠右边界时执行(防止单列重复填充) if (k != M - 1 - k) { for (int i = N - 2 - k; i > k; i--){ arr[i][k] = nums++; } } } int main(){ // 计算需要处理的环层数:覆盖所有完整环+中间单行/单列 int layers = (min(N, M) + 1) / 2; for (int k = 0; k < layers; k++){ circle(k); } printArr(); return 0; }
关键修改说明
- 移除冗余的
p变量:原p的作用可以通过当前环层数k直接计算,避免额外变量带来的逻辑混乱; - 修正
circle函数的填充逻辑:- 左到右直接用
k作为顶部行索引,去掉绕弯的N-N+k写法; - 上到下从
k+1开始,避免和左到右的最后一个元素重复赋值; - 新增边界判断:当只剩一行时跳过右到左填充,只剩一列时跳过下到上填充,防止重复覆盖;
- 左到右直接用
- 调整循环层数计算:用
(min(N, M) + 1) / 2确定环数,无论N/M是奇数还是偶数,都能覆盖所有层,包括中间的单行/单列。
测试示例
设置N=5,M=3,输出为:
1 2 3 12 13 4 11 14 5 10 15 6 9 8 7
设置N=3,M=5,输出为:
1 2 3 4 5 12 13 14 15 6 11 10 9 8 7
这样不管N和M是奇数还是偶数,代码都能正常工作,且完全保留了你原有的代码结构。
内容的提问来源于stack exchange,提问作者user16870582
相关产品推荐
相关产品推荐

