Страницы

Поиск по вопросам

воскресенье, 7 июля 2019 г.

Получение ближайших элементов в массиве

Дан двумерный массив:
static int[][] multi = new int[][] { {2, 0, 4, 1241, 424, 1, 12323}, {1, 3, 5, 7}, {321, 320, 32, 41241, -11, -12, -13, -66, -688} };
Нужно создать метод, который принимает индекс определенного элемента и int range - количество элементов, находящихся рядом с элементом. Метод должен вернут массив. Например:
nearby(0, 2, 2) вернет 2, 0, 1241, 424
Я сделал что-то вроде:
public static int[] nearby(int x, int y, int range) { int index = 1; ArrayList leftSize = new ArrayList(); ArrayList rightSize = new ArrayList(); while (index != range + 1) { leftSize.add(multi[x][y - index]); rightSize.add(multi[x][y + index]); index += 1; } leftSize.addAll(rightSize); int[] stockArr = new int[leftSize.size()]; return stockArr; }
Но не уверен, что это лучшее решение. Какой алгоритм использовать, чтобы работать напрямую с массивом, не создавая ArrayList?


Ответ

Если опустить проверки границ, то получается так:
public static int[] nearby(int x, int y, int range) { int[] result = new int[range * 2]; System.arraycopy(multi[x], y - range, result, 0, range); System.arraycopy(multi[x], y + 1, result, range, range); return result; }
Результат:
[2, 0, 1241, 424]

Если при выходе за границы массива дело должно кончаться не ArrayIndexOutOfBoundsException, а возвратом только допустимых элементов (вплоть до пустого массива), то проще сделать через список:
public static int[] nearby(int x, int y, int range) { if (x < 0 || x >= multi.length) return new int[0]; List result = new ArrayList<>(); for (int i = Math.max(y - range, 0); i <= y + range && i < multi[x].length; i++) { if (i != y) { result.add(multi[x][i]); } } return result.stream().mapToInt(e -> e).toArray(); }
Альтернативным вариантом, с использованием только массивов, тут будет предварительный расчет границ копируемых участков (leftFirst, leftLast, rightFirst, rightLast), но восприниматься это будет тяжелее:
public static int[] nearby(int x, int y, int range) { if (x < 0 || x >= multi.length || y - range >= multi[x].length || y + range < 0) return new int[0]; int leftFirst = Math.max(y - range, 0); int leftLast = Math.min(y - 1, multi[x].length - 1); int leftLength = leftLast - leftFirst + 1; int rightFirst = Math.min(y + 1, multi[x].length); int rightLast = Math.min(y + range, multi[x].length - 1); int rightLength = rightLast - rightFirst + 1; int[] result = new int[leftLength + rightLength]; System.arraycopy(multi[x], leftFirst, result, 0, leftLength); System.arraycopy(multi[x], rightFirst, result, leftLength, rightLength); return result; }

Комментариев нет:

Отправить комментарий