JavaRush /Java блог /Java Developer /Решаем задачи на одномерные и двумерные массивы
Анзор Кармов
31 уровень
Санкт-Петербург

Решаем задачи на одномерные и двумерные массивы

Статья из группы Java Developer
В данной статье будут рассмотрены (а в большей степени, даны для самостоятельного разбора) задачи на массивы. Будем качать свои скиллы в следующих направлениях:
  1. Одномерные массивы

    1. Задачи “Продолжи последовательность”;
    2. Задачи на поиск элементов;
    3. Задачи на сортировку элементов массива.
  2. Двумерные массивы

    1. Задачи “Построй матрицу вида”;
    2. Задачи “Найди элементы в самых неожиданных местах (строки, столбцы, диагонали )”;
    3. Задачи “Расставь корабли для водного сражения”.
Для всех задач мы будем использовать массивы целых чисел. Решаем задачи на одномерные и двумерные массивы - 1

Задачи на одномерные массивы

Продолжи последовательность

В данном ряде задач вам необходимо будет:
  1. Определить закономерность, согласно которой формируется та или иная числовая последовательность.
  2. Написать функцию, которая формирует первые N элементов данной последовательности в виде целочисленного массива и выводит элементы массива на экран.
Предположим, перед нами стоит задача продолжить следующий числовой ряд:

1, 2, 3, 4, 5…
Шаг 1: определить закономерность. Тут все элементарно — это ряд натуральных чисел. Шаг 2: напишем функцию, которая будет формировать первые N элементов данного ряда в виде массива:

public class Main {

    public static void main(String[] args) {
        System.out.println(Arrays.toString(createArrayOfIntegers(10)));

        // Output: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    }

    public static int[] createArrayOfIntegers(int n) {
        int[] array = new int[n];
        for (int i = 1; i <= n; i++) {
            array[i-1] = i;
        }

        return array;
    }
}
Аналогичным образом необходимо написать функции, которые продолжили бы следующие последовательности:

A. 2,  4,  6,   8,  10...
B. 1,  3,  5,   7,   9...
C. 1,  4,  9,  16,  25...
D. 1,  8, 27,  64, 125...
E. 1, -1,  1,  -1,   1,  -1...
F. 1, -2,  3,  -4,   5,  -6...
G. 1, -4,  9, -16,  25....
H. 1,  0,  2,   0,   3,   0,  4....
I. 1,  2,  6,  24, 120, 720...
J. 1,  1,  2,   3,   5,   8, 13, 21…

Поиск элементов

В данном ряде задач необходимо найти в готовом массиве элемент, обладающий какими-то свойствами. Например, максимальный по значению элемент. Для демонстрации напишем код функции, которая принимает в себя массив и определяет индекс максимального элемента в массиве, а затем выводит данный элемент вместе с его индексом в консоль. Также продемонстрирую, как c помощью класса java.util.concurrent.ThreadLocalRandom можно быстро сгенерировать целочисленный массив заданной длины, состоящий из случайных элементов:

public class Main {

    public static void main(String[] args) {
        int[] array = generateRandomIntArray(10);
        findMax(array);
        
        /*
        Output: 
        Generated random array: [50551934, -551646189, 410352642, 1822778873, -1744293692, -1140287711, 878876868, -2116893120, -797503442, -703924530]
        Max element is [1822778873] with index [3]
        */
        
    }


    public static int[] generateRandomIntArray(int n) {
        int[] array = ThreadLocalRandom.current().ints().limit(n).toArray();
        System.out.println("Generated random array: " + Arrays.toString(array));
        return array;
    }

    public static void findMax(int[] array) {
        int maxIndex = 0;
        int max = array[maxIndex];
        for (int i = 1; i < array.length; i++) {
            if (array[i] > max) {
                max = array[i];
                maxIndex = i;
            }
        }

        System.out.println(String.format("Max element is [%d] with index [%d]", max, maxIndex));
    }
}
Теперь сами задачи. Из массива случайных целочисленных элементов нам нужно найти:
  1. Максимум.
  2. Минимум.
  3. Среднее арифметическое.
  4. Количество элементов между максимальным и минимальным элементом.
  5. Первое простое число.
  6. Последнее простое число.
  7. Количество простых чисел в массиве.
Можно выводить как значение, так и индексы. Если нет искомого элемента, вывести это на экран, как вам удобно. Для последней задачи необходимо подготовить отсортированный по возрастанию массив целочисленных элементов. В данном массиве необходимо найти элемент по значению за минимальное количество операций (Подсказка).

Сортировка

В данном ряде задач необходимо отсортировать массив целочисленных элементов, используя различные алгоритмы сортировки. Материалов в сети по различным алгоритмам довольно много. Попробуйте сначала понять суть алгоритма, а затем попробуйте самостоятельно его реализовать. Сначала на бумаге (блок схема, псевдокод, как вам удобно), а затем в IDEA. Алгоритмы для реализации:
  • сортировка пузырьком;
  • сортировка выбором;
  • сортировка вставками;
  • сортировка слиянием.

Задачи на двумерные массивы

Нарисуй матрицу

В следующем ряде задач необходимо рисовать (выводить в консоль) двумерные массивы (матрицы), составленные определенным образом: они должны соответствовать паттерну, заданному задачей. Приведу пример. Нам необходимо построить и вывести на экран матрицу m*n (где m — количество строк, а n — количество элементов в строке) вида:

1, 2, 3, 4
5, 6, 7, 8
9,10,11,12
Напишем функцию, которая сделает все за нас, а также, приведем функцию, которая будет красиво выводить матрицу в консоль (возможно, она вам пригодится):

public class Main {

    public static void main(String[] args) {
        createAndDrawMatrix(3, 4);

    }

    public static void createAndDrawMatrix(int m, int n) {
        int[][] matrix = new int[m][n];

        int value = 1;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                matrix[i][j] = value;
                value ++;
            }
        }
        
        printMatrix(matrix);
    }
    
    public static void printMatrix(int[][] matrix) {
        for (int[] array : matrix) {
            for (int anInt : array) {
                System.out.print(String.format("%3d", anInt));
            }
            System.out.println();
        }
    }
}
Теперь задачи: Вывести на экран матрицу m*n вида: 4, 3, 2, 1 8, 7, 6, 5, 12,11,10, 9 ----------- 1, 4, 7 2, 5, 8 3, 6, 9 ----------- 9, 8, 7 6, 5, 4 3, 2, 1 ----------- 12,11,10, 9 8, 7, 6, 5, 4, 3, 2, 1

Поиск элементов

В данном разделе необходимо реализовать поиск различных элементов в различных частях матрицы: в определенном столбце или же в определенной строке. Предположим, у нас есть матрица вида: -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 В качестве примера найдем количество отрицательных элементов в третьей строке:

public class Main {

    public static void main(String[] args) {
        int [][] matrix = {
                { -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}
        };

        findNegativeCountInRow(matrix, 3);
    }

    private static void findNegativeCountInRow(int[][] matrix, int rowNumber) {
        int negativeCount = 0;
        for (int element : matrix[rowNumber]){
            if (element < 0) {
                negativeCount ++;
            }
        }

        System.out.println("Matrix: ");
        printMatrix(matrix);
        System.out.println(String.format("Has %d negative elements in #%d row ", negativeCount, rowNumber));

    }

    public static void printMatrix(int[][] matrix) {
        for (int[] array : matrix) {
            for (int anInt : array) {
                System.out.print(String.format("%5d", anInt));
            }
            System.out.println();
        }
    }
}
В результате выполнения метода main, в консоль будет выведено:

Matrix: 
   -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
Has 3 negative elements in #3 row 
Теперь задачи. Для любого нечетного n вывести матрицу n*n вида:

1,  -2,  3,  
-4,  5, -6,
7,  -8,  9
Из данной матрицы вывести:
  • все отрицательные элементы;
  • все отрицательные элементы в строке i;
  • все отрицательные элементы в столбце j;
  • все элементы диагонали (начиная с левого верхнего угла);
  • все элементы диагонали (начиная с левого нижнего угла).

Морской бой

Последний раздел со звездочкой: без подсказок и примеров. Матрицы идеально подходят для программирования игры морской бой. Одним из этапов программирования данной игры является расстановка кораблей на игровом поле. Если вы решите ряд данных задач, будьте уверены, морской бой вам по зубам. Итак, дана матрица 10х10, состоящая из нулей. Предположим, что она является полем для игры в морской бой. В данном поле 0 — пустая ячейка, 1 — корабль, либо часть корабля. Написать функции, каждая из которых по правилам игры морской бой расставляет случайным образом:
  • 10 однопалубных кораблей;
  • 10 двухпалубных корбалей;
  • 5 трехпалубных кораблей;
  • расставляет все корабли для игры в морской бой (4 однопалубных, 3 двухпалубных, 2 трехпалубных, 1 четырехпалубный).
Вот и все! Как и с любой темой в программировании, с массивами лучше всего разбираться на практике. Удачной разминки!
Комментарии (13)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Илья Уровень 30
23 мая 2020
"Если вы решите ряд данных задач, будьте уверены, морской бой вам по зубам. " - очень и очень спорное утверждение! Решил все задачи, кроме сортировки слиянием, но до приобретения навыка рандомно расставлять корабли на поле так же далеко, как калеке пешком от Калининграда до Камчатки.
Илья Уровень 30
17 мая 2020
Не могу понять, почему при заполнении массива по убыванию, вывод происходит с точность наоборот...

int[][] matrix3 = new int[3][3];
        int count3 = 1;
        for (int i = matrix3.length-1; i >= 0 ; i--) {
            for (int j = matrix3[i].length-1; j >= 0 ; j--) {
                matrix3[i][j] = count3++;
                System.out.print(matrix3[i][j] + "\t");
            }
            System.out.println();
        }
В моем понимании должна получиться матрица {9, 8, 7 6, 5, 4 3, 2, 1} так как заполнение массива начинается с matrix[2][2] (matrix[i][j] на первой итерации вложенного цикла), т.е. по идее должно быть matrix[2][2] = 1, matrix[2][1] = 2, matrix[2][0] = 3 и т.д. Почему массив заполняется в порядке возрастания?
Илья Уровень 30
14 мая 2020
Делая сортировку выбором, решил её дополнить поиском максимального значения, чтобы сортировка шла сразу с двух сторон, но что-то пошло не так... Алгоритмы тяжело даются, нужна помощь (вопросы в скрине ниже) Спасибо! мой код:

System.out.println("----------- SELECTION SORT -----------");// левый эл сравнивается с каждым правым, после чего левый эл = мин числу из текущей итерации. Далее второй левый эл сравнивается с каждым правым и т.д.
        int[] selectionArray = new int[6];
        for (int i = 0; i < selectionArray.length; i++) {
            selectionArray[i] = (int) (Math.random() * 30);
        }
        System.out.println(Arrays.toString(selectionArray) + " - стартовый массив");

for (int i = 0; i < selectionArray.length; i++) {
            int min = i;
            int max = selectionArray.length-1-i;
            for (int j = i+1; j < selectionArray.length; j++) { // сравнивается [1] с [0], [2] с [0], [3] с [0],...
                if (selectionArray[j] < selectionArray[min])  // мин ч присваивается [0]'лю (min)
                    min = j;
                if (selectionArray[selectionArray.length-1-j] > selectionArray[max])
                    max = selectionArray.length-1-j;
            }                                               // после чего:
            int tmpMin = selectionArray[i]; // создаем переменную для временного хранения значения
            selectionArray[i] = selectionArray[min]; // меняем местами первый элемент (если он не является минимальным) с минимальным элементом
            selectionArray[min] = tmpMin; 

            int tmpMax = selectionArray[selectionArray.length-1-i];
            selectionArray[selectionArray.length-1-i] = selectionArray[max];
            selectionArray[max] = tmpMax;
            System.out.println(Arrays.toString(selectionArray));
        }
        System.out.println(Arrays.toString(selectionArray) + " - итоговый массив");
    }
Илья Уровень 30
10 мая 2020
Что значит "найти элемент по значению" в последней (восьмой) задаче раздела "Поиск элементов" (одномерный массив)?
Pineapple_1365 Уровень 5
30 апреля 2020
Я читаю но ничего не понятно