题意:
假如有矩阵(二维数组):
1 2 3 4
5 6 7 8
9 10 11 12
12 14 15 16
则依次打印出数字:1,2,3,4,8,12,16,15,14,12,9,5,6,7,11,10
即顺时针打印。
几种需要注意的情况:
第一种:
1 2 3
4 5 6
结果为:1,2,3,6,5,4
第二种:
1
2
3
结果为:1,2,3
第三种:
1 2 3
结果为:1,2,3
以上三种是数字不足一圈的情况,也需要考虑进去。
分析:
这道题有好几种解法,如考虑到每一圈的起点都是左上角的坐标,如(0,0),(1,1),(2,2)....(startX,startY)坐标是每一圈的起点,假设该数字矩阵为n*m,则只要满足n>startX*2并且m>startY*2就可以以(startX,startY)为起点打印新的一圈,反之结束打印。接下来的问题就是如何打印一圈。就是分成四步来打印,这里不做讨论。
这里另一种解法思路:
分四步打印矩形:
1.从左到右,当等于截止点即跳转到第二步(这里的截止点是不固定,打印第一圈该截止点是矩阵的列数,接下来该截止点每次递减1)
2.从上到下,同上,当等于截止点则跳到第三步(这里的截止点变为矩阵行数)
3.从右到左,当等于截止点则跳转到第四步(这里的截止点初始值为-1,之后每次递增1)
4.从下到上,同上(这里的截止点的初始值为0,之后每次递增1)
java代码如下:
public class PrintMatrixInCircle {
public static void main(String[] args) {
// 循环打印数组数字
int[][] datas = new int[][] {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
int rows = datas.length; //
int clos = rows > 0 ? datas[0].length : 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < clos; j++) {
System.out.format("%-3d", datas[i][j]);
}
System.out.println();
}
System.out.print("The Result Is:");
print(datas);
}
public static void print(int[][] datas) {
if (datas == null||datas.length==0)
return;
int rows = datas.length;//矩阵行数
int clos = rows > 0 ? datas[0].length : 0; //矩阵列数
int left = -1;//从右往左打印截止点
int up = 0;//从下往上打印截止点
int i = 0; //行坐标
int j = 0;//列坐标
int type = 0;//打印类型,0表示从左到右,1表示从上到下,2表示从右到左,3表示从下到上
int count = 0; //打印次数,当打印次数等于矩阵数字总数则打印结束
int sums = rows * clos; //矩阵数字总数
while (count < sums) {
count++;
switch (type) {
case 0: { // 向右
System.out.print(datas[i][j] + " ");
j++;
if (j == clos) {
j--;// 下一个坐标
i++;
type = 1;
clos--;//截止点递减1
}
}
break;
case 1: { // 向下
System.out.print(datas[i][j] + " ");
i++;// 向下
if (i == rows) {
i--;
j--;
type = 2;
rows--;
}
}
break;
case 2: { // 向左
System.out.print(datas[i][j] + " ");
j--;// 向左
if (j == left) {
j++;
i--;
type = 3;
left++;
}
}
break;
case 3: { // 向上
System.out.print(datas[i][j] + " ");
i--;
if (i == up) {
i++;
j++;
type = 0;
up++;
}
}
break;
}
}
}
输出结果:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
The Result Is:1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10