黑马程序员——螺旋方阵的打印

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

import java.util.Scanner;

/*
 * 写一方法,打印等长的二维数组,要求从1开始的自然数由方阵的
 * 最外圈向内螺旋方式地顺序排列。 如: n = 4 则打印:
 * 	1	2	3	4
 12	13	14	5
 11	16	15	6
 10	9	8	7
 分析:
 用数组下标来表示上面的输出:
 [0][0] [0][1] [0][2] [0][3]
 [1][0] [1][1] [1][2] [1][3]
 [2][0] [2][1] [2][2] [2][3]
 [3][0] [3][1] [3][2] [3][3]
 从1开始给二维数组的赋值顺序是:
 从左向右:行下标不变,列下标递增
 从上向下:列下标不变,行下标递增
 从右向左:行下标不变,列下标递减
 从下向上:列下标不变,行下标递减
 由此可见:给数组赋值分为4个不同的状态,我们可以给每个状态定个标志来判断
 赋值的方向,当前状态赋值完毕后自动更改状态值进入下一状态。
 那么,怎么判断当前状态赋值完毕呢?
 可以发现该数组正好是一个方阵,一轮赋值完成以后正好是一个正方形。正方形的4个角可以当做4个拐点
 第一轮赋值		第二轮赋值
 拐点0:	00			11
 拐点1:	03			12
 拐点2:	33			22
 拐点3:	30			21
 发现拐点与数组长度和赋值轮数有关
 当第一轮赋值时拐点1为:数组长度-1-0
 当第二轮赋值时拐点1为:数组长度-1-1
 所以可以把第一轮赋值定义为第0轮,以此类推。。。
 直到了赋值规律,我们怎么用循环完成赋值呢:可以使用continue控制循环
 因为是从1开始赋值,所以最大值正好等于数组的长度:一直赋值,直到等于数组的长度,
 每完成一次赋值使用continue跳出本次循环,继续下次判断赋值
 */
public class Test7 {

	public static void main(String[] args) {
		// 键盘录入n值
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入你要打印的二维数组arr[n][n]方阵n的值:");
		int n = sc.nextInt();
		// 写一个方法创建数组并赋值
		int[][] arr = makeArr(n);
		//遍历数组
		for(int[] ar:arr){
			for(int i :ar){
				System.out.print(i+"\t");
			}
			System.out.println();
		}
	}

	private static int[][] makeArr(int n) {
		// 创建数组
		int[][] arr = new int[n][n];
		// 赋值
		// 首先定义几个变量
		int flag = 0; // 定义状态标识
		int t = 0; // 定义数组行下标
		int r = 0; // 定义数组列下标
		int c = 0;// 定义第几轮赋值
		int s = n * n;// 定义赋值的最大值
		int len = n;// 定义数组长度

		// 一直赋值直到最大值
		for (int x = 1; x <= s; x++) {

			// 当flag=0时,从左向右赋值,t不变,r++
			if (flag == 0) {
				// 如果r=len-1-c则另flag=1
				if (r == len - 1 - c) {
					flag = 1;
				} else {
					arr[t][r] = x;
					r++;
					// 每完成一次赋值使用continue跳出循环,使x++
					continue;
				}
			}

			// 如果以n=4来说,此时arr[0][3]还没有赋值,即从上向下的第一个元素还没有值
			// 当flag=1时,从上向下赋值,r不变,t++
			if (flag == 1) {
				// 如果t=len-1-c则令flag=2
				if (t == len - 1 - c) {
					flag = 2;
				} else {
					arr[t][r] = x;
					t++;
					continue;
				}
			}

			// 当flag=2时,从右向左赋值,t不变r--
			if (flag == 2) {
				// 如果r=c则令flag=3
				if (r == c) {
					flag = 3;
				} else {
					arr[t][r] = x;
					r--;
					continue;
				}
			}

			// 当flag=3时,从下向上赋值,r不变,t--
			if (flag == 3) {
				// 如果t=c+1时,说明一轮赋值完成,这时需要重置标识值,并c++,且列数也要自加
				if (t == c + 1) {
					// 由于此处的元素还没有赋值,先赋值
					arr[t][r] = x;
					flag = 0;// 重置标识值
					c++;// 轮数加1
					r++;// 列数加1
					continue;
				} else {
					arr[t][r] = x;
					t--;
					continue;
				}
			}
		}
		//至此,赋值完毕
		return arr;
	}
}


你可能感兴趣的:(经典案例)