* 需求:
* 写一方法,打印等长的二维数组,要求从1开始的自然数由方阵的最外圈向内螺旋方式地顺序排列。 如: n = 4 则打印:
* 1 2 3 4
* 12 13 14 5
* 11 16 15 6
* 10 9 8 7
*
*思路:
*1.想要按数组的顺序将数字添加进该数组中,发现是很麻烦的,因为数字规律很难找
*可以想到,按数字自然顺序添加,这样就要操作数组的角标
*2.看出该数组中元素是螺旋的被添加进数组,可以定义按圈添加元素,这样对角标的操作
*比较有规律,每一行(或列)添加n-1个元素就可以使四个方向每次添加的元素都相等,都是n-1个
*3.关键要定义每次开始时的坐标,可见每次添加都有一个坐标是固定的,这样也减少了问题的复杂程度
*4.按圈添加就出先 了一个问题,第二圈怎么办,不能一直不停的写代码,所以想到用递归,控制递归的条件
*让程序顺利停止,最后打印该数组
*5.将代码进行封装,可根据具体细节操作
*
*步骤:
*1.定义二维数组,基数base由用户传入,还应用到圈数circle和往数组添加的自然数num
*2.定义功能用于给"一圈"元素进行赋值操作:第一次由左向右,一维数组坐标不变,一维数组元素的坐标
*一次递加,而每往里一圈相应的坐标都要加1所以[circle][circle+x],其他三个方向也是同样道理。
*3.当用户传入的base为奇数时,到最后会存在base=1的情况,最里面只有一个数 ,
* 里面的坐标是 [arr.length/2][arr.length/2]
* 4.当base-1大于0时,也就是每次需要往一行(或者列)里添加的元素个数大于0就要递归。
* 5.定义打印二维数组功能
*/
package cn.heima.test1;
public class PrintNum {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
printNum(7);
}
public static void printNum(int base){
//定义等长的二维数组
int[][] arr = new int[base][base];
//定义圈数,为了便于定义代码,圈数从0开始
int circle = 0;
//要添加进数组的数值
int num = 0;
addArrElement(arr,base,circle,num);
printArr(arr); //执行打印
}
//定义功能用来向数组的"每一圈"添加元素
public static void addArrElement(int[][] arr,int base,int circle,int num){
//(base-1)*4代表每一圈的数值个数
//x代表赋值一圈的数值,y做为计数器使用
for(int x=0,y=0;x<(base-1)*4;x++){
//由左向右赋值
if(x<base-1){
arr[circle][circle+x] = ++num;
}
//由上向下赋值
else if(x<2*base-2){
arr[circle+y++][arr.length-1-circle]=++num;
}
//由右向左赋值
else if(x<3*base-3){
arr[arr.length-1-circle][circle+(y--)]=++num;
}
//由下向上赋值
else if(x<4*base-4){
arr[arr.length-1-circle-(y++)][circle]=++num;
}
}
//圈数增加1
circle++;
//往里面添加的元素个数每次减少两个 ,因为少一圈有两个数没了
base -= 2;
//当base为奇数时,存在base=1的情况,最里圈只有一个数
if(base==1)
arr[arr.length/2][arr.length/2]=++num;
//只要基数还大于1就要继续递归
if(base>1)
addArrElement(arr,base,circle,num);
}
//打印二维数组
public static void printArr(int[][] arr){
//用for循环嵌套打印
for(int x=0;x<arr.length;x++){
for(int y=0;y<arr[x].length;y++){
System.out.print(arr[x][y]+"\t");
}
//为了打印效果,多换行几次
System.out.println();
System.out.println();
System.out.println();
}
}
}
|