Не получается поместить элементы в массив

Рейтинг: 1Ответов: 3Опубликовано: 25.01.2023

Задача заключается в том, чтобы создать массив из чисел, размер которого равен умножению N на X. Например: 2 * 5 = 10 >>> {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}.

Далее нужно отсортировать числа так, чтобы массив вывел лишь те числа, которые делятся на N. Например, в этом случае: {2, 4, 6, 8, 10}.

Проблема заключается в том, чтобы поместить в массив результат. Если создавать новый массив - нужен изначальный размер, который я узнаю лишь после второго фора. Пожалуйста, подскажите и помогите, никак не могу разобраться:(((

Прикрепляю код снизу. Всем большое спасибо за помощь!

public static void main(String[] args) {

    int n = 2;
    int x = 5;
    int mult = n * x;
    int[] array = new int[mult];



    for (int i = 0; i < mult; i++) {
        array[i] = i + 1;

    }
    System.out.println(Arrays.toString(array));


    for (int j = 0;j < array.length; j++){
        if (j%n==0){
            int q = j;

            System.out.println(q);
        }
    }
    System.out.println(Arrays.toString(array));
}

Ответы

▲ 2Принят

По сути задача сводится к тому, чтобы получить X чисел, кратных N, то есть, последовательность N, N*2, N*3,.. N*X и её можно решить многими способами.

Для начала следует представить решение в виде функции, принимающей два аргумента, и возвращающей результат в виде массива.

  • Вариант 1. Цикл.
    Создаётся массив из X чисел, который заполняется в цикле числами, кратными N:
// 1.1 умножение
public static int[] getXmultiplesOfN(int x, int n) {
    int[] res = new int[x];
    for (int i = 0; i < x;) {
        res[i] = ++i * n;
    }
    return res;
}

// 1.2 сложение
public static int[] getXmultiplesOfN(int x, int n) {
    int[] res = new int[x];
    for (int i = 0, v = n; i < x; i++, v += n) {
        res[i] = v;
    }
    return res;
}

  • Вариант 2. Arrays::setAll.
    Для заполнения массивов значениями, которые зависят от индекса, можно использовать метод Arrays::setAll, для которого следует определить функцию-генератор значений:
public static int[] getXmultiplesOfN(int x, int n) {
    int[] res = new int[x];

    Arrays.setAll(res, i -> ++i * n); // i - индексы в диапазоне [0, x - 1]

    return res;
}
  • Вариант 3. Stream API
    В данном случае в функциональном стиле определяется нужная последовательность чисел при помощи различных методов IntStream, которая трансформируется в массив.

IntStream.iterate

public static int[] getXmultiplesOfN(int x, int n) {
    return IntStream.iterate(n, i -> i + n) // последовательность n, n * 2,...
        .limit(x)   // взять X элементов
        .toArray(); // преобразовать в массив
}

IntStream.rangeClosed

public static int[] getXmultiplesOfN(int x, int n) {
    return IntStream.rangeClosed(1, x) // посл-ть "индексов" в диапазоне [1, X]
        .map(i -> i * n) // домножить на N каждый "индекс"
        .toArray();      // и преобразовать в массив
}

Если всё-таки нужно удалять элементы из какого-то промежуточного "массива", то лучше сгенерировать динамический массив или список значений от 1 до N*X (List<Integer>), а потом либо отфильтровать его, либо удалить ненужные значения непосредственно.

```java
public static int[] getXmultiplesOfN(int x, int n) {
    List<Integer> list = IntStream.rangeClosed(1, x * n).boxed().collect(Collectors.toList());
    System.out.println(list); // вывод всех промежуточных значений

    return list.stream()
            .filter(i -> i % n == 0) // оставить кратные числа
            .mapToInt(i -> i)        // IntStream
            .toArray();              // получить массив
}

Результат - Integer[]

public static Integer[] getXmultiplesOfN(int x, int n) {
    List<Integer> list = IntStream.rangeClosed(1, x * n).boxed().collect(Collectors.toList());
    System.out.println(list);        // вывод всех промежуточных значений
    list.removeIf(i -> i % n != 0);  // удалить некратные числа
    return list.toArray(new Integer[0]);  // преобразовать в массив
}
▲ 1

А как насчет стримов? Данная задача с помощью StreamApi решается за 3 секунды:

import java.util.Arrays;
import java.util.stream.IntStream;

public class Main {

    public static void main(String[] args) {
        int [] result = generate(2, 5);
        System.out.println(Arrays.toString(result));
    }

    public static int[] generate(int n, int x) {
        return IntStream.iterate(n, i -> i + n).limit(x).toArray();
    }
}
▲ 0

Можешь использовать коллекции, к примеру.

Если тебе предпочтительнее решить через обычные массивы, то я придумал только такое решение:

    public static void main(String[] args) {
    int n = 2;
    int x = 5;
    int mult = n * x;
    int[] array = new int[mult];

    for (int i = 0; i < mult; i++) {
        array[i] = i + 1;
    }

    System.out.println(Arrays.toString(array));

    int count = 0;

    for (int j = 0;j < array.length; j++){
        if (j%n==0){
            System.out.println(j);

            array[count] = j;
            count++;
        }
    }

    int[] result = new int[count];

    for (int index = 0; index < count; index++) {
        result[index] = array[index];
    }
    
    System.out.println(Arrays.toString(result));
}