为了账号安全,请及时绑定邮箱和手机立即绑定

是否有一个函数可以按给定顺序不断增加矩阵中的数字

是否有一个函数可以按给定顺序不断增加矩阵中的数字

largeQ 2023-10-13 17:24:49
我必须创建一个矩阵(N*M),其中每个单元格根据特定遍历的顺序进行标记。问题是我让它只适用于(N N)。我一直在寻找一个解决方案,以便它也适用于(N M)。例如 N*M 的示例:1  2  5  104  3  6  119  8  7  12N*N 的示例:1  2  5  10 4  3  6  11 9  8  7  12 16 15 14 132x4 看起来像:1 2 5 74 3 6 84x2 看起来像:1 24 35 67 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();              }           }
查看完整描述

3 回答

?
慕标5832272

TA贡献1966条经验 获得超4个赞

根据您在我的第一个答案下的评论:


我也在考虑另一种解决方案......使用 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 您只需根据您所在的位置跳过列或行(检查矩阵总是绑定 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,忽略最后两列。同样,如果行大于列。对于a,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;

}

例如使用 args 调用上述方法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 > columns or rows < 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, *, *]

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


查看完整回答
反对 回复 2023-10-13
?
萧十郎

TA贡献1815条经验 获得超13个赞

如果您查看 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矩阵了。1创建一个包含从到 的奇数的列表columns-1,通过逐个添加列表的元素来填充第一行,每次迭代后将列表中的第 i 个数字替换为-1能够使用该行的列表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();

        }

    }

}


查看完整回答
反对 回复 2023-10-13
?
牧羊人nacy

TA贡献1862条经验 获得超7个赞

如果你沿着左栏看,就会发现一个模式:


 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);

  }

}


查看完整回答
反对 回复 2023-10-13
  • 3 回答
  • 0 关注
  • 125 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信