n×m矩阵指定尺寸子方阵求和方法 附3×3示例及实现问题
矩阵子方阵总和计算:通用方法与实操问题排查
通用问题:n×m矩阵的指定尺寸L子方阵总和计算
要计算所有尺寸为L的子方阵总和,核心是先明确合法子方阵的判定规则:对于n行m列的矩阵,所有L×L子方阵必须满足尺寸不超过矩阵短边长度,即L ≤ min(n,m),否则不存在合法的子方阵。遍历的核心是锚定每个子方阵的左上角坐标,再根据尺寸确定覆盖范围,全程严格按照索引边界做判断,避免数组越界。
实操场景:3×3矩阵全尺寸子方阵遍历计算
给定如下3×3测试矩阵:
2 2 3 3 4 5 4 5 5
场景要求遍历所有合法子方阵,覆盖1×1、2×2两类尺寸:
- 1×1尺寸:共9个,每个矩阵元素本身即为独立子方阵
- 2×2尺寸:共4个,分别为矩阵内覆盖的四个独立2×2块:
2 2 3 42 3 4 53 4 4 54 5 5 5
原有代码的逻辑错误定位
用户原有实现代码如下:
for (i=0; i<n-l; i++){ for (j=1; j<n-i+1; j++){ sum = 0; for (p=i; p<l+i; p++){ for (q=1; q<l+j+1; q++){ sum += a[p][q]; } } cout << sum << endl; } l++; }
逐点梳理代码存在的逻辑问题:
- 外层行循环边界错误:原代码行循环条件为
i < n - l,正确边界应为i <= n - l。前者会漏掉行坐标为n-l的最后一行子方阵,导致计算范围缺失 - 列维度边界判断缺失:原代码全程没有使用矩阵列数
m做边界校验,默认按照正方形矩阵的逻辑用行数n判断列范围,当矩阵为非正方形时必然出现越界或漏算问题 - 列索引规则不匹配:原代码列方向循环从索引1开始计数,和编程中矩阵数组通用的0起始索引规则不匹配,会遗漏首列元素、甚至访问数组越界
- 尺寸递增时机错误:原代码在单轮所有同尺寸子方阵遍历尚未完成时,就在外层行循环的末尾执行
l++,会提前改变子方阵尺寸,导致遍历范围错位 - 行、列遍历逻辑未解耦:原代码将列方向的偏移量和动态变化的
i值绑定,没有独立维护列方向的合法遍历范围,最终会出现数组越界、计算结果错误的问题
正确实现逻辑与参考代码
按照矩阵遍历的通用规则,正确的实现流程为:
- 确定所有可能的子方阵尺寸范围:从1到矩阵的最小边长,即
1 ≤ l ≤ min(n,m),跳过不存在合法子方阵的尺寸 - 对每个固定的子方阵尺寸
l,遍历所有合法的左上角坐标:- 行方向范围:从0到
n-l,保证从该位置开始取l行不会超出矩阵行数边界 - 列方向范围:从0到
m-l,保证从该位置开始取l列不会超出矩阵列数边界
- 行方向范围:从0到
- 对每个确定的左上角坐标,遍历子方阵覆盖的所有元素范围(行范围从
i到i+l-1,列范围从j到j+l-1),累加得到该子方阵的总和
参考实现代码(与原代码同为C++语法风格):
// 矩阵a为n行m列,已完成初始化 for (int l = 1; l <= min(n, m); l++) { // 遍历所有合法的左上角行坐标 for (int i = 0; i <= n - l; i++) { // 遍历所有合法的左上角列坐标 for (int j = 0; j <= m - l; j++) { int sum = 0; // 累加当前l*l子方阵的所有元素 for (int p = i; p < i + l; p++) { for (int q = j; q < j + l; q++) { sum += a[p][q]; } } cout << "尺寸" << l << "的子方阵(左上" << i << "," << j << ")总和:" << sum << endl; } } }
对应3×3测试矩阵的实际计算结果:
- 1×1尺寸子方阵总和依次为:2、2、3、3、4、5、4、5、5
- 2×2尺寸子方阵总和依次为:11、14、16、19
内容的提问来源于stack exchange,提问作者Abhilash
相关产品推荐
相关产品推荐

