前两天的一道考试题,刚拿到手头都大了,不过功夫不负有心人,经过大半天努力 还是搞出来了。可能方法有点笨了,有高手有更好的方法,求指点
题目是这样的: 写一方法,打印等长的二维数组,要求从1开始的自然数由方阵的最外圈向内螺旋方式地顺序排列。 如: n = 4 则打印:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
- package com.itheima;
- import java.util.Scanner;
- public class Test9 {
- public static void main(String[] args) {
- // 输入数组长度
- System.out.print("请输入数组长度:");
- Scanner sc = new Scanner(System.in);
- int n = sc.nextInt();
- // 打印从1开始的自然数开始由方阵的最外圈向内螺旋方式地顺序排列的数组
- printArray(n);
- }
- /**
- * 打印指定长度的等长二维数组
- * */
- public static void printArray(int n) {
- // 构造一个空的数组
- Integer[][] it = new Integer[n][n];
- // 将起始元素设置为 1
- it[0][0] = 1;
- // 定义起始元素Point对象
- Point p = new Point(0, 0, 1);
- // 设定初始方向,向右
- int flg = 1;
- // 代表数组设值得方向
- Direction d = null;
- // 一次循环可以设值的个数,为零代表已经将数组填满
- int step = 0;
- // 循环维数组设置从自然数1开始的连续的值
- while (true) {
- // 方向依次为右下左上
- d = Direction.getDirection(flg);
- // 获取本次循环可以设置的元素个数
- step = Direction.nextPoint(p, d, it);
- // 为零代表已经将数组填满
- if (step == 0) {
- break;
- }
- // 返回下次循环开始的点
- p = setValue(p, d, step, p.getV(), it);
- // 方向依次改变
- flg++;
- }
- // 循环打印给数组中的值
- for (int i = 0; i < it.length; i++) {
- for (int j = 0; j < it[i].length; j++) {
- System.out.print(it[i][j] + "\t");
- }
- // 折行
- System.out.println();
- }
- }
- /**
- * 给定点,给定方向和该方向上的空元素数,将该方向上的空元素依次设值,并返回最后一个元素,返回的元素需要改变方向
- * */
- public static Point setValue(Point p, Direction d, int step, int value,
- Integer[][] it) {
- // 获取元素坐标和方向
- int a = p.getA();
- int b = p.getB();
- int y = d.getY();
- int x = d.getX();
- // 循环累加给定点的值,并赋到数组中去
- for (int k = 0; k < step; k++) {
- it[a = a + y][b = b + x] = ++value;
- }
- // 返回最后一个点
- return new Point(a, b, value);
- }
- }
- /**
- * 代表数组中一个数组元素
- * */
- class Point {
- // a表示二维维数,
- private int a = 0;
- // b表示一维脚标
- private int b = 0;
- // v表示数组元素的值
- private int v = 0;
- public int getA() {
- return a;
- }
- public int getB() {
- return b;
- }
- public int getV() {
- return v;
- }
- // 构造方法
- public Point(int a, int b, int v) {
- this.a = a;
- this.b = b;
- this.v = v;
- }
- }
- /**
- * 方向类,将二维数组看成坐标系,左右为x轴,上下为y轴,将方向表示为(y,x)对应数组脚标
- * 方向向右表示为(0,1),向下为(1,0),向左(0,-1),向上(-1,0)
- * */
- class Direction {
- // 向右为(0,1)
- private static Direction rD = new Direction(0, 1);
- // 向下为(1,0)
- private static Direction dD = new Direction(1, 0);
- // 向左为(0,-1)
- private static Direction lD = new Direction(0, -1);
- // 向上为(-1,0)
- private static Direction uD = new Direction(-1, 0);
- // 定义y轴和x轴的坐标值
- private int y = 0;
- private int x = 0;
- public int getY() {
- return y;
- }
- public int getX() {
- return x;
- }
- // 构造方法,初始化方向类即指定相应坐标
- public Direction(int y, int x) {
- this.y = y;
- this.x = x;
- }
- /**
- * 给定原点和方向,获取可以移动的步数
- */
- public static int nextPoint(Point p, Direction d, Integer[][] it) {
- // 接收参数的坐标值
- int a = p.getA();
- int b = p.getB();
- int v = p.getV();
- // 可以移动的步数
- int step = 0;
- // 移动的方向
- int direct = 0;
- Point newP = null;
- // 判断移动的方向
- if ((direct = d.getX()) != 0) {
- if (direct > 0) {
- // x轴向右移动,直到不为空,得到移动的步数
- while (true) {
- if (isNullPoint(a, ++b, it)) {
- step++;
- continue;
- }
- break;
- }
- } else {
- // x轴向左移动,直到不为空,得到移动的步数
- while (true) {
- if (isNullPoint(a, --b, it)) {
- step++;
- continue;
- }
- break;
- }
- }
- } else {
- // 在y轴上移动
- direct = d.getY();
- if (direct > 0) {
- // 在y轴上向下移动
- while (true) {
- if (isNullPoint(++a, b, it)) {
- step++;
- continue;
- }
- break;
- }
- } else {
- // 在y轴上向上移动
- while (true) {
- if (isNullPoint(--a, b, it)) {
- step++;
- continue;
- }
- break;
- }
- }
- }
- return step;
- }
- /**
- * 给定数组的维数脚标,判断数组中的某个元素是否为空 false不为空,true为空
- * */
- public static boolean isNullPoint(int a, int b, Integer[][] it) {
- // 维数脚标不合法,返回false
- if (a >= it.length || b >= it.length || a < 0 || b < 0) {
- return false;
- }
- // 判断值是否为空
- if (it[a][b] == null) {
- return true;
- } else {
- return false;
- }
- }
- /**
- * 获取移动的方向,首先向右移动
- */
- public static Direction getDirection(int flg) {
- // 方向依次是右下左上,通过取余判断
- if (flg % 4 == 1) {
- return rD;
- } else if (flg % 4 == 2) {
- return dD;
- } else if (flg % 4 == 3) {
- return lD;
- } else {
- return uD;
- }
- }
- }
复制代码
|