Java实现的按照顺时针或逆时针方向输出一个数字矩阵功能示例

时间:2021-07-30 21:14:21

本文实例讲述了java实现的按照顺时针或逆时针方向输出一个数字矩阵功能。分享给大家供大家参考,具体如下:

题目:按照指定的长宽和输出方向,从外向内打印一个从 1 开始的数字矩阵,矩阵的开始位置在左上角。如下图

Java实现的按照顺时针或逆时针方向输出一个数字矩阵功能示例

代码及注释如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
public class numbermatrix {
  public static void main(string[] args) {
    int width = 25;
    int height = 12;
    boolean clockwise = false;
    system.out.println("服务器之家测试结果:");
    outputmatrix(width, height, clockwise);
  }
  /**
   * 按照指定的长宽和输出方向,从外向内打印一个从 1 开始的数字矩阵,矩阵的开始位置在左上角。
   *
   * @param width   矩阵宽度
   * @param height  矩阵高度
   * @param clockwise 是否是顺时针方向
   */
  private static void outputmatrix(int width, int height, boolean clockwise) {
    // 首先判断最大数字的位数,以决定输出如何对齐
    int numlength = (int) math.log10(width * height) + 1;
    // 决定输出的格式(最大位数 + 1个空格)
    string format = "%" + (numlength + 1) + "d";
    // 定义要输出的二维数组,注意维度是从高到低的
    // 此时 matrix 中所有元素的值都是 0
    int[][] matrix = new int[height][width];
    // 定义一个位置指针和一个计数器,位置指针进行移动,而计数器负责递增,递增后的数字
    // 被填充进矩阵,当 width * height 个数字填充完毕,这个矩阵就完成了。
    // 注意这里位置指针的第一个元素对应 matrix 的第一个维度 y,第二个元素对应第二个维度 x。
    int[] pointer = {0, 0};
    int counter = 1;
    // 定义当前移动的方向:1、2、3、4 分别表示上、右、下、左。
    // 顺时针的起始方向为右,逆时针的起始方向为下。
    int direction = clockwise ? 2 : 3;
    // 开始循环填充,每个填充分为三步
    for (int i = 1, max = width * height; i <= max; i++) {
      // 1. 填充内容
      int y = pointer[0];
      int x = pointer[1];
      matrix[y][x] = counter;
      // 2. 计数器自增
      counter += 1;
      // 3. 移动到下一个位置,因为这地方比较复杂,所以开个方法实现
      direction = move(matrix, width, height, pointer, direction, clockwise);
    }
    // 矩阵填充完毕,按照正常的方式循环输出即可
    for (int y = 0; y < height; y++) {
      for (int x = 0; x < width; x++) {
        system.out.printf(format, matrix[y][x]);
      }
      system.out.println(); // 完成一行后输出换行
    }
  }
  /**
   * 在矩阵中移动
   *
   * @param matrix  矩阵,用于判断前进方向的下一个位置是否已经填充了数字,如果是则转向
   * @param width   矩阵的宽
   * @param height  矩阵的高
   * @param pointer  指针的当前位置。调用本方法后里面的值会改变,除非方法返回 0
   * @param direction 指针当前移动的方向
   * @param clockwise 是否是要按顺时针方向转向
   *
   * @return 移动后的新方向(与原来的方向可能相同也可能不同)。如果无法再继续移动,则返回 0
   */
  private static int move(int[][] matrix, int width, int height, int[] pointer, int direction, boolean clockwise) {
    // 先尝试按照原来的方向移动到 newpointer
    int[] newpointer = movedirectly(pointer, direction);
    // 检查 newpointer 是否合法,如果合法则将其赋值给 pointer 并保持原来的方向,方法完成
    if (isvalid(newpointer, matrix, width, height)) {
      system.arraycopy(newpointer, 0, pointer, 0, 2);
      return direction;
    }
    // 进行转向,重新从 pointer 朝新的方向移动
    direction = turn(direction, clockwise);
    newpointer = movedirectly(pointer, direction);
    // 检查 newpointer 是否合法(同前面一样)
    if (isvalid(newpointer, matrix, width, height)) {
      system.arraycopy(newpointer, 0, pointer, 0, 2);
      return direction;
    }
    // 既无法前进也无法转向,那么无法继续移动。
    return 0;
  }
  // 判断矩阵中指定的位置是否可以填充
  private static boolean isvalid(int[] newpointer, int[][] matrix, int width, int height) {
    // 位置不能超出矩阵范围
    if (newpointer[0] >= height
        || newpointer[0] < 0
        || newpointer[1] >= width
        || newpointer[1] < 0) {
      return false;
    }
    // 位置的内容应该为空
    if (matrix[newpointer[0]][newpointer[1]] != 0) {
      return false;
    }
    return true;
  }
  // 转向。根据我们对 direction 的定义,顺时针就是 +1,逆时针就是 -1
  private static int turn(int direction, boolean clockwise) {
    int newdirection = clockwise ? direction + 1 : direction - 1;
    if (newdirection > 4) {
      newdirection = 1;
    } else if (newdirection < 1) {
      newdirection = 4;
    }
    return newdirection;
  }
  /**
   * 朝指定的方向移动,并返回新的位置
   *
   * @param pointer  当前位置
   * @param direction 方向
   *
   * @return 新的位置
   */
  private static int[] movedirectly(int[] pointer, int direction) {
    int y = pointer[0];
    int x = pointer[1];
    switch (direction) {
      case 1:
        return new int[]{y - 1, x};
      case 2:
        return new int[]{y, x + 1};
      case 3:
        return new int[]{y + 1, x};
      case 4:
        return new int[]{y, x - 1};
    }
    throw new illegalargumentexception("方向不正确: " + direction);
  }
}

运行结果:

Java实现的按照顺时针或逆时针方向输出一个数字矩阵功能示例

希望本文所述对大家java程序设计有所帮助。

原文链接:http://blog.csdn.net/YidingHe/article/details/49924735