【问题标题】:Is there a function which keeps increasing a number in a matrix in given order是否有一个函数可以按给定顺序不断增加矩阵中的数字
【发布时间】:2019-10-10 22:12:25
【问题描述】:

我必须创建一个矩阵 (N*M),其中每个单元格都根据特定遍历的顺序进行标记。

问题是我只为 (NN) 工作。我一直在寻找解决方案,因此它也适用于 (NM)。

例如 N*M 示例:

1  2  5  10

4  3  6  11

9  8  7  12

N*N 示例:

1  2  5  10 

4  3  6  11 

9  8  7  12 

16 15 14 13

2x4 看起来像:

1 2 5 7

4 3 6 8

4x2 看起来像:

1 2

4 3

5 6

7 8

代码

public static int matrix[][];
       public static void main(String[] args) {

        borderLayout(5);
        print();
       }

       public static void borderLayout(int size) {
           matrix = new int[size][size];
           for(int i = 0 ; i < size ; i ++) {
               fillBorder(i);
           }
       }

       public static void fillBorder(int n) {
           int number = n*n+1;
           int row = n;
           int column = 0;


           for(column = 0; column<=n; column++) {
               System.out.println("COLUMN DRAWING");
               matrix[row][column]=number++;
           }

           column--;

           for(row = n; row>0 ; row--){
               System.out.println("ROW DRAWING");
               matrix[row-1][column] = number++;
           }

           print();
           System.out.println("");

       }

       private static void print() {

              int x = matrix.length;
              int y = matrix[0].length;

              for (int i = 0; i < x; i++) {

                 for (int j = 0; j < y; j++) {

                    System.out.print(matrix[j][i]);
                    System.out.print(" ");
                    if (matrix[j][i] < 10) {
                       System.out.print(" ");
                    }
                 }

                 System.out.println();
              }

           }

【问题讨论】:

  • 您能否也为2 x 4 矩阵或4 x 2 添加预期输出
  • 2x4 看起来像:1 2 5 7 4 3 6 8 4x2 看起来像:1 2 4 3 5 6 7 8

标签: java matrix


【解决方案1】:

在我的第一个答案下关注您的 cmets:

我也在考虑另一种解决方案......使用 BFS。对于一个起点,假设 0,0 每次迭代总是进入深度 1,所以如果你从 0,0 开始,你会做 1,0 1,1 0,1 并且当你到达边界时,无论是行还是列,你都会增加深度意味着在下一次迭代中,您使用 0,2 1,2 2,2 2,1 2,0 如果矩阵是 nxm 且 n!=m 您只需根据您所在的位置跳过 col 或行(检查矩阵总是绑定 m 和 n)。

忘了提,这样它也适用于字母 好吧。

我决定添加一个新答案,而不是编辑第一个答案。

由于我对图表和广度优先搜索不是很熟悉,因此无法对基于 BSF 的算法提供任何建议。

但我想我理解您对如何进行操作的想法,这是一种天真的方法来实现它。您希望在每次迭代中采取的步骤

0,0
-----
0,1
1,1
1,0
-----
0,2
1,2
2,2
2,1
2,0
-----
0,3
1,3
2,3
3,3
3,2
3,1
3,0
...

不管矩阵是否为正方形,我最初都专注于正方形区域。例如,如果是4x6矩阵,我只看4x4部分,忽略最后两列。同样,如果行大于列。对于7x5,我将查看5x5 并忽略最后两行。在每次迭代中,我将使用两个内部循环,第一个用于递增行,第二个用于递减列。

与上一个答案不同,这次我将使用一个字符串数组来满足您的这个评论:

忘了提,这样它也适用于字母 好吧。

static String[][] fillArray(int rows, int columns){
    char ch = 'A';
    String[][] matrix = new String[rows][columns];
    int square = Math.min(rows, columns);
    for(int i = 0; i < square; i++){
        String curr = String.valueOf(ch);
        for(int r = 0; r <= i ; r++){
            matrix[r][i] = curr;
        }
        for(int c = i-1; c >= 0; c--){
            matrix[i][c] = curr;
        }
        ch++;
    }
    return matrix;
}

例如使用参数4x5调用上述方法

public static void main(String[] args) {
    String[][] filled = fillArray(4,5);
    for(String[] row: filled){
        System.out.println(Arrays.toString(row));
    }
}

会导致

[A, B, C, D, null]
[B, B, C, D, null]
[C, C, C, D, null]
[D, D, D, D, null]

现在让我们看看仍然被null 填充的被忽略区域,即rows &gt; columns or rows &lt; columns 的情况。为简单起见,我将使用* 填写此区域。

static String[][] fillArray(int rows, int columns){
    char ch = 'A';
    String[][] matrix = new String[rows][columns];
    int square = Math.min(rows, columns);
    for(int i = 0; i < square; i++){
        String curr = String.valueOf(ch);
        for(int r = 0; r <= i ; r++){
            matrix[r][i] = curr;
        }
        for(int c = i-1; c >= 0; c--){
            matrix[i][c] = curr;
        }
        ch++;
    }

    ch = '*';
    if (rows > columns) {
        for (int i = square; i < rows; i++) {
            for (int j = 0; j < columns; j++) {
                matrix[i][j] = String.valueOf(ch);
            }
        }
    }
    if (rows < columns) {
        for (int i = square; i < columns; i++) {
            for (int j = 0; j < rows; j++) {
                matrix[j][i] = String.valueOf(ch);
            }
        }
    }
    return matrix;
}

调用fillArray(4,6)

public static void main(String[] args) {
    String[][] filled = fillArray(4,6);
    for(String[] row: filled){
        System.out.println(Arrays.toString(row));
    }
}

现在应该导致:

[A, B, C, D, *, *]
[B, B, C, D, *, *]
[C, C, C, D, *, *]
[D, D, D, D, *, *]

这篇文章比我想象的要长。但我希望它很容易理解。

【讨论】:

    【解决方案2】:

    如果您查看您的 nxn 矩阵,则可以识别出某种模式。

       1    2    5   10   17 
       4    3    6   11   18 
       9    8    7   12   19 
      16   15   14   13   20 
      25   24   23   22   21 
    
    • 第一列总是有平方数
    • 在从最小平方数 1 开始的第一行中,您将添加奇数序列,即1,3,5,7,9,11 ....

    每一行的模式

    [1]  +1 +3 +5 +7 ....
    [4]  -1 +3 +5 +7 ....
    [9]  -1 -1 +5 +7 ....
    [16] -1 -1 -1 +7 ....
    [25] -1 -1 -1 -1 ....
    

    有了这些知识,现在很容易填充n x n 矩阵。使用从1columns-1 的奇数创建一个列表,通过一个接一个地添加列表的元素来填充第一行,每次迭代后用-1 替换列表中的第i 个数字以便能够使用i+1th 行的列表。

    现在对于一个非方阵,你可以使用上面的方法来填充矩阵的方格区域,并分别处理剩余的行或列。找到正方形区域的大小以定义其余行/列的计数器相对简单。

    只要计算Math.pow(Math.min(rows, columns), 2);

    我采用了您的方法名称并稍微更改了您的打印方法。我没有评论代码,但希望很清楚正在做什么。如果有任何不清楚的地方,请随时询问。

    import java.util.List;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
    
    public class Test{
    
        public static int matrix[][];
    
        public static void main(String[] args) {
            borderLayout(5, 5);
            print();
        }
    
        public static void borderLayout(int rows, int columns) {
            //create a list (1,3,5, ...) with size = columns - 1
            List<Integer> list = IntStream.iterate(1, i -> i + 2)
                    .limit(columns - 1).boxed()
                    .collect(Collectors.toList());
            matrix = new int[rows][columns];
            int square = Math.min(rows, columns);
            for (int i = 0; i < square; i++) {
                int temp = (i + 1) * (i + 1);
                for (int j = 0; j < square; j++) {
                    if (j == 0) {
                        matrix[i][j] = temp;
                    } else {
                        matrix[i][j] = matrix[i][j - 1] + list.get(j - 1);
                    }
                }
                if (i < columns - 1) {
                    list.set(i, -1);
                }
            }
            if (rows > columns) {
                int counter = (int) Math.pow(Math.min(rows, columns), 2);
                int sqrt = (int) Math.sqrt(counter);
                for (int i = sqrt; i < rows; i++) {
                    for (int j = 0; j < columns; j++) {
                        matrix[i][j] = ++counter;
                    }
                }
            } else if (rows < columns) {
                int counter = (int) Math.pow(Math.min(rows, columns), 2);
                int sqrt = (int) Math.sqrt(counter);
                for (int i = sqrt; i < columns; i++) {
                    for (int j = 0; j < rows; j++) {
                        matrix[j][i] = ++counter;
                    }
                }
            }
        }
    
        private static void print() {
            for (int[] row : matrix) {
                for (int i : row) {
                    System.out.printf("%4d ", i);
                }
                System.out.println();
            }
        }
    }
    

    【讨论】:

    • 这看起来很复杂。为什么不matrix[r][c] = (r &gt; c) ? ((r + 1)*(r + 1) + c) : (c * c + 1 + r);
    • 你真的觉得这很复杂吗?我发现代码运算符相当不可读。但这可能是一个品味问题。
    • 如果你愿意,可以用 if/else 来写。它仍然少了很多代码。
    • @Eritrean 谢谢,它对我有用,我刚刚接受了你的回答!
    • 我也在考虑另一种解决方案......使用 BFS。对于一个起点,假设 0,0 每次迭代总是进入深度 1,所以如果你从 0,0 开始,你会做 1,0 1,1 0,1,当你到达边界时,无论是行还是列,你都会增加深度意味着在下一次迭代中,您使用 0,2 1,2 2,2 2,1 2,0 如果矩阵是 nxm 且 n!=m 您只需根据您所在的位置跳过 col 或行(检查矩阵总是绑定 m 和 n)。大家觉得怎么样?
    【解决方案3】:

    如果你沿着左栏看,有一个模式:

     1
     4
     9
    16
    

    (r + 1)^2,其中r 是行号。

    沿行,该值减 1,直到r == c 的对角线:

     1
     4  3 
     9  8  7
    16 15 14 13
    

    这是(r + 1)^2 - c

    如果你沿着顶行看,有一个图案:

    1   2   5   10
    

    这是c^2 + 1

    向下列行,值增加1,直到r == c的对角线:

    1   2   5   10
        3   6   11
            7   12
                13
    

    这是c^2 + 1 + r

    所以你可以使用嵌套循环计算数组元素:

    for (int r = 0; r < N; ++r) {
      for (int c = 0; c < M; ++c) {
        matrix[r][c] = (r >= c) ? ((r + 1)*(r + 1) - c) : (c * c + 1 + r);
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      相关资源
      最近更新 更多