回形方阵是用自然数以回形的方式填充的方阵,这里的回形填充是指从矩阵左上角开始,按顺时针方向从外向内螺旋依次地填充。如一个5阶的回形方阵:
1
2
3
4
5
16
17
18
19
6
15
24
25
20
7
14
23
22
21
8
13
12
11
10
9
\begin{matrix} 1 & 2 & 3 & 4 & 5\\ 16 & 17 & 18 & 19 & 6\\ 15 & 24 & 25 & 20 & 7\\ 14 & 23 & 22 & 21 & 8\\ 13 & 12 & 11 & 10 & 9 \end{matrix}
11615141321724231231825221141920211056789
本代码采用按回型填充循序赋值的方法,生成回形矩阵。(元素的位置和值之间可能会有数学关系)
public class HuiShapeArray {
public static void main(String[] args) {
final int length = 6, N = length * length; //这里设定方阵的边长,计算了方阵的元素总个数
int[][] arr = new int[length][length]; //用arr存储方阵
final int[][] dirc = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } }; //这里定义的是可能的填充方向,依次为:右,下,左,上
int i = 0, j = 0, n = 1, cur = 0, N = length * length; //i表示行号,j表示列号,n表示要填充的数,cur表示转向次数
boolean outline = true; //表示填充区域在不在矩阵边界处
while (n <= N) { //每次循环填充一个元素,总共循环length^2次
arr[i][j] = n; //填充
n++; //下一个要填充的数
i += dirc[cur][0]; //下一个要被填充位置的行号(假设不转向)
j += dirc[cur][1]; //下一个要被填充位置的列号(假设不转向)
if ((outline && (j >= length || i >= length || j < 0)) || arr[i][j] != 0) { //若未转向步进的位置超出矩阵的序号范围或已经赋过值(若outline为false则跳过超范围判断)
i -= dirc[cur][0]; //回退一步
j -= dirc[cur][1];
cur = (cur + 1) % 4; //更改转向次数,使其可以定位下一次转向的方向
i += dirc[cur][0]; //前进一步
j += dirc[cur][1];
if (outline && cur == 3) { //转向3次后,已脱离矩阵边界,进入矩阵内部
outline = false;
}
}
}
//打印生成的方阵
for (i = 0; i < length; i++) {
for (j = 0; j < length; j++) {
System.out.print(arr[i][j] + "\t");
}
System.out.println();
}
}
}