Есть ли функция, которая продолжает увеличивать число в матрице в заданном порядке - PullRequest
2 голосов
/ 11 октября 2019

Мне нужно создать матрицу (N * M), в которой каждая ячейка помечена в соответствии с их порядком с определенным обходом.

Проблема в том, что он у меня работает только (N N). Я застрял, чтобы найти решение, чтобы оно также могло работать для (N M).

Например, Пример с 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();
              }

           }

Ответы [ 3 ]

0 голосов
/ 11 октября 2019

Если вы посмотрите вдоль левого столбца, есть шаблон:

 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

, чтоis 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);
  }
}
0 голосов
/ 12 октября 2019

После ваших комментариев под моим первым ответом:

Я думал также о другом решении ... С 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 и игнорирую последние два столбца. Аналогично, если строки больше столбцов. Для 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 > 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, *, *]

Этот пост стал длиннее, чем я думал. Но я надеюсь, что это довольно легко понять.

0 голосов
/ 11 октября 2019

Если вы посмотрите на свою матрицу 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();
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...