二维数组螺旋遍历输出异常求助:元素输出不全修复
修复二维数组螺旋遍历的转向与剩余元素处理问题
我看了你的代码,问题出在最后处理剩余元素的条件判断逻辑上——你用了r <= c和r >= c来决定输出行还是列,但这个判断逻辑忽略了循环结束后行边界是否有效(比如当行数为偶数时,循环结束后r_beg > r_end,此时即使列边界有效,也没有剩余行需要输出),导致部分场景下剩余元素没有被正确输出,比如你提到的3×7矩阵。
问题分析
以你的3×7矩阵为例:
- 循环执行
min(3,7)/2 = 1次后,边界更新为r_beg=1, r_end=1, c_beg=1, c_end=5。 - 此时剩余的是第1行(索引从0开始)的第1到5列元素(9-13),但原代码的条件判断逻辑在某些场景下会失效,比如当行数为偶数时会错误输出已遍历元素,而在你的测试场景中可能因为边界判断的疏漏导致剩余元素未被输出。
正确的逻辑应该是:循环结束后,只有当行边界和列边界都有效时(r_beg <= r_end && c_beg <= c_end),再判断剩余的是单行还是单列:
- 如果
r_beg == r_end:说明只剩一行,遍历该行的剩余列; - 如果
c_beg == c_end:说明只剩一列,遍历该列的剩余行。
修正后的代码
把你原代码最后的if-else部分替换成以下逻辑,同时保持其他部分不变:
#include <iostream> #include <algorithm> using namespace std; int main() { freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); int r, c; cin >> r >> c; int r_beg = 0, r_end = r - 1, c_beg = 0, c_end = c - 1; int **m = new int*[r]; for (int i = 0; i < r; i++) { m[i] = new int[c]; for (int j = 0; j < c; j++) { cin >> m[i][j]; } } // 遍历外层循环 for (int runs = min(r, c) / 2; runs--;) { // 顶行:左到右(不包含最后一个元素,留给右列) for (int i = c_beg; i < c_end; i++) cout << m[r_beg][i] << " "; // 右列:上到下(不包含最后一个元素,留给底行) for (int i = r_beg; i < r_end; i++) cout << m[i][c_end] << " "; // 底行:右到左(不包含第一个元素,留给左列) for (int i = c_end; i > c_beg; i--) cout << m[r_end][i] << " "; // 左列:下到上(不包含第一个元素,留给顶行) for (int i = r_end; i > r_beg; i--) cout << m[i][c_beg] << " "; // 收缩边界 r_beg++; c_beg++; r_end--; c_end--; } // 处理剩余的单行或单列 if (r_beg <= r_end && c_beg <= c_end) { if (r_beg == r_end) { // 只剩一行,遍历列 for (int i = c_beg; i <= c_end; ++i) { cout << m[r_beg][i] << " "; } } else if (c_beg == c_end) { // 只剩一列,遍历行 for (int i = r_beg; i <= r_end; ++i) { cout << m[i][c_beg] << " "; } } } // 释放内存 for (int i = 0; i < r; i++) delete[] m[i]; delete[] m; return 0; }
测试验证
对于你给出的3×7矩阵输入:
3 7 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
修正后的代码会输出:1 2 3 4 5 6 7 14 21 20 19 18 17 16 15 8 9 10 11 12 13
完全符合预期。
对于3×3矩阵输入,输出也会正确得到1 2 3 6 9 8 7 4 5。
内容的提问来源于stack exchange,提问作者v_head
相关产品推荐
相关产品推荐

