Объединение элементов в зубчатые 2D-массивы в один новый зубчатый 2D-массив (проблема с Deep Copy)
Учитывая два зубчатых массива: a и b, где a + b всегда будет иметь одинаковое количество строк:
int[][] a = { {1,2}, {4,5,6} };
int[][] b = { {7}, {8,9,0} };
как я могу манипулировать новым зубчатым массивом c для возврата:
{ {1,2,7}, {4,5,6,8,9,0} }
?
Вот что я до сих пор:
int[][] c = null;
for(int i = 0; i<a.length; i++){
c = new int[a.length][a[i].length + b[i].length];
}
//rest of my code for assigning the values into the appropriate position works.
Проблема, как вы все видите, состоит в том, что я выполняю глубокую копию, которая на второй итерации цикла for устанавливает строки ВСЕ на длину длины текущей строки на шаге итерации.
Ответы
Ответ 1
Недостаток в вашем подходе
Вы создаете новый объект 2D-массива на каждой итерации цикла. Каждый раз вы переназначаете c
, тем самым выбрасывая всю свою предыдущую работу. Кроме того, одновременное размещение номера в обоих наборах скобок приводит к каждой строке с одинаковой длиной.
Используя ваш пример, первый раз через цикл, c
присваивается двумерному массиву с двумя строками, каждая из трех длин. Во второй раз через цикл вы выбрасываете свой предыдущий 2D-массив и создаете новый, имеющий две строки, каждая из шести.
Но вам нужно создавать новую строку каждый раз через цикл, а не весь 2D-массив.
Решение
Сначала мы создаем 2D-массив с именем c
и указываем, что он имеет строки a.length
. Мы не ставим значение во вторую скобку, потому что это указывает на то, что все строки имеют одинаковую длину. Итак, на данный момент c
не знает о длине строки. Он просто знает, сколько строк оно может иметь. Имейте в виду: c
на самом деле не имеет никаких строк, просто емкость для строк a.length
.
Далее, мы должны создать строки и назначить им длину/емкость. Мы установили наш цикл для запуска столько раз, сколько строк. Индекс текущей строки обозначается i
, и поэтому c[i]
относится к определенной строке в массиве 2D c
. Мы используем new int[]
для создания каждой отдельной строки/массива, но внутри скобок мы должны указывать длину текущей строки. Для любой строки c[i]
ее длина задается суммой длин a[i]
и b[i]
; то есть a[i].length + b[i].length
.
Остается массив c
, содержащий строки/массивы, каждый из которых имеет заданную длину/емкость, соответствующую сумме соответствующих строк строк в a
и b
.
Имейте в виду, что c
по-прежнему не содержит целых значений, только те контейнеры, которые имеют правильный размер, сохраняют значения в a
и b
. Как вы уже упоминали, у вас уже есть код для заполнения массива значениями.
int[][] c = new int[a.length][];
for (int i = 0; i < a.length; i++) {
c[i] = new int[a[i].length + b[i].length];
}
Ответ 2
При инициализации Java 2D массива рассмотрим его как таблицу; вам нужно только указать количество строк, и в каждой строке таблицы может быть разное количество столбцов.
Eg. Скажем, у нас есть двумерный массив c, определяемый следующим образом:
int[][] c = new int[10][];
В нем указано, что вы определили c содержит 10 элементов int []. Но для его использования вы должны определить количество столбцов, которые каждая строка имеет.
Eg. Скажем, у нас есть 3 столбца во второй строке
int c[1] = new int[3];
Итак, в этом примере вам нужно добавить значения столбцов 2D-массивов a
и b
для вычисления результирующего массива, который равен c
.
c[i] = new int[a[i].length + b[i].length];
Это даст вам то, что вы ожидали.
int[][] a = { {1,2}, {4,5,6} };
int[][] b = { {7}, {8,9,0} };
int[][] c = new int[a.length][];
for(int i = 0; i<a.length; i++){
c[i] = new int[a[i].length + b[i].length];
for (int j=0;j< a[i].length; j++) {
c[i][j] = a[i][j];
}
int length = a[i].length;
for (int j=0;j< b[i].length; j++) {
c[i][length+j] = b[i][j];
}
}
Ответ 3
Попробуйте c[i] = new int[a[i].length + b[i].length]
Ответ 4
int[][] c = new int[a.length][];
for(int i = 0; i < c.length; i++){
c[i] = new int[a[i].length + b[i].length];
int x = 0;
for (int num : a[i]) {
c[i][x] = num;
x++;
}
for (int num : b[i]) {
c[i][x] = num;
x++;
}
}
или даже проще...
int[][] c = new int[a.length][];
for(int i = 0; i < c.length; i++){
c[i] = new int[a[i].length + b[i].length];
System.arraycopy(a[i], 0, c[i], 0, a[i].length);
System.arraycopy(b[i], 0, c[i], a[i].length, b[i].length);
}
Ответ 5
Попробуйте следующее:
int[][] c = new int[a.length][];
for(int i = 0; i<a.length; i++){
c[i] = new int [a[i].length + b[i].length];
int j;
for(j=0; i < a[i].length; j++){
c[i][j] = a[i][j];
}
for(int k=0; i < b[i].length; k++){
c[i][j+k] = b[i][j];
}
}
Ответ 6
public static void main (String [] args) {
int[][] a = { {1,2}, {4,5,6} };
int[][] b = { {7}, {8,9,0} };
int[][] c = null;
for(int i = 0; i<a.length; i++){
c = new int[a.length][a[i].length + b[i].length];
}
for(int i = 0; i<a.length; i++){
for (int j = 0; j < a[i].length+b[i].length; j++) {
if(j< a[i].length){
c[i][j]=a[i][j];
}
if(j< a[i].length+b[i].length && j>= a[i].length){
c[i][j]=b[i][j-a[i].length];
}
}
}
for(int i = 0; i<a.length; i++){
for (int j = 0; j < a[i].length+b[i].length; j++) {
System.out.print(c[i][j]);
}
System.out.println();
}
}
Это работает в моей системе...........