#include <iostream>
using namespace std;
#define M 4
#define N 5
void init(int* arr, int m, int n) {
for (int i = 1; i <= m * n; ++i) {
arr[i - 1] = i;
}
}
//定义四个方向的界限,不够优化
int* spiralMatrix(int matrix[M][N], int m, int n) {
int* trace = new int[m * n];
int step = 0;
int left = 0;
int right = n - 1;
int up = m - 1;
int down = 1;
int direct = 1;
while (true) {
if (direct == 1) {
for (int i = left; i <= right; ++i) {
trace[step++] = matrix[down - 1][i];
}
left++;
direct++;
} else if (direct == 2) {
for (int i = down; i <= up; ++i) {
trace[step++] = matrix[i][right];
}
down++;
direct++;
} else if (direct == 3) {
for (int i = right - 1; i >= left - 1; --i) {
trace[step++] = matrix[up][i];
}
right--;
direct++;
} else {
for (int i = up - 1; i >= down - 1; --i) {
trace[step++] = matrix[i][left - 1];
}
up--;
direct = 1;
}
if (step == m * n)
break;
}
return trace;
}
/*
* 优解:考虑每一圈起始点的规律(start,start)
* 只考虑起始坐标和x,y上的界限关系,省去2个界限start*2<cols&&start*2<rows
* 规律更加清晰
*/
int* spiralMatrix2(int matrix[M][N], int rows, int cols) {
int* trace = new int[rows * cols];
int step = 0;
int start = 0;
int endX = cols - 1 - start;
int endY = rows - 1 - start;
while (start * 2 < rows && start * 2 < cols) {
//向右:至少有一格,即start<=endX
for (int i = start; i <= endX; ++i) {
trace[step++] = matrix[start][i];
}
//向下:至少2行,即start<endY
if (start < endY) {
for (int i = start + 1; i <= endY; ++i) {
trace[step++] = matrix[i][endX];
}
}
//向左:至少2行且至少2列,即start<endY&&start<endX
if (start < endX && start < endY) {
for (int i = endX - 1; i >= start; --i) {
trace[step++] = matrix[endY][i];
}
}
//向上:至少3行且至少2列,即start<endY-1&&start<endX
if (start < endX && start < endY - 1) {
for (int i = endY - 1; i >= start + 1; --i) {
trace[step++] = matrix[i][start];
}
}
start++;
endX = cols - 1 - start;
endY = rows - 1 - start;
}
return trace;
}
int main() {
int matrix[M][N] = { 0 };
init(matrix[0], M, N);
int* trace1 = spiralMatrix(matrix, M, N);
int* trace2 = spiralMatrix2(matrix, M, N);
for (int i = 0; i < M * N; ++i) {
cout << trace1[i] << " ";
}
cout << endl;
for (int i = 0; i < M * N; ++i) {
cout << trace2[i] << " ";
}
return 0;
}