Что лучший способ состоит в том, чтобы обнулить все значения трехмерной антенной решетки в Java?

В чем разница?

Родовые ассоциированные типы (GAT) - это ассоциированные типы , которые сами являются родовыми . RFC начинается с мотивирующего примера , выделенного мной:

Рассмотрим следующую черту в качестве типичного мотивирующего примера:

trait StreamingIterator {
    type Item<'a>;
    fn next<'a>(&'a mut self) -> Option>;
}

Эта черта очень полезна - он допускает своего рода Итератор, который выдает значения, время жизни которых связано с временем жизни ссылки, переданной в next. Конкретным очевидным вариантом использования этой черты будет итератор по вектору, который дает перекрывающиеся изменчивые субликсы с каждой итерацией. При использовании стандартного интерфейса Iterator такая реализация была бы недействительной, поскольку каждый срез должен был бы существовать столько же, сколько итератор, чем столько, сколько заимствование, инициированное next.

Эта черта не может быть выражена в Rust, как она существует сегодня , потому что она зависит от своего рода полиморфизма высшего рода. Этот RFC расширил бы Rust, чтобы включить эту специфическую форму полиморфизма с более высоким родом, который упоминается здесь как конструкторы связанного типа. Эта особенность имеет ряд применений, но основное применение имеет те же черты, что и черта StreamingIterator: определение черт, которые дают типы, срок жизни которых связан с локальным заимствованием типа получателя.

blockquote>

Обратите внимание, что связанный тип Item имеет общее время жизни 'a. Большинство примеров в RFC используют время жизни, но есть также пример, использующий универсальный тип :

trait PointerFamily {
    type Pointer: Deref;
    fn new(value: T) -> Self::Pointer;
}
blockquote>

Обратите внимание, что связанный тип Pointer имеет универсальный тип T.

Ваш конкретный пример.

. Чем отличается Generic от предыдущего примера от этого общего связанного типа

blockquote>

. GAT не поможет вашему случаю, который, по-видимому, не требует ассоциированного типа, который сам по себе является общим.

11
задан 14 revs, 7 users 33% 17 May 2009 в 19:10
поделиться

8 ответов

Если вы используете JDK 1.5 или выше:

    for (int[][] square : cube) {
        for (int[] line : square) {
            Arrays.fill(line, 0);
        }
    }
29
ответ дан 3 December 2019 в 00:43
поделиться

Что ж, вы всегда можете сделать это:

Arrays.fill(cube[0][0],0);
Arrays.fill(cube[0],cube[0][0]);
Arrays.fill(cube,cube[0]);

Это немного чище, чем 3 цикла.

Если вы не поняли, первая "заливка" заполняет одно измерение , Вторая заливка копирует это одно измерение в двух измерениях. Третья заливка копирует два измерения в трех измерениях.

Если у вас нет других ссылок на массив, который нужно сохранить, воссоздание его, как предлагали другие, вероятно, будет быстрее и чище.

2
ответ дан 3 December 2019 в 00:43
поделиться

Просто создайте новый массив и назначьте ему переменную ... Сборщик мусора очистит старый массив

1
ответ дан 3 December 2019 в 00:43
поделиться

Если все строки имеют ту же длину, что вы могли бы просто отбросить массив и построить новый, поскольку значение по умолчанию для элементов int равно нулю.

cube = new int[cube.length][cube[0].length][cube[0][0].length];

Или вы можете сделать

for(int[][] tda : cube ) {
  for(int[] oda : tda) {
    java.util.Arrays.fill(oda, 0);
  }
}
1
ответ дан 3 December 2019 в 00:43
поделиться

После инициализации массив будет заполнен нулями:

int[][][] cube = new int[10][20][30];

Это вы также можете сделать позже, чтобы сбросить массив в ноль, это не ограничивается объявлением:

cube = new int[10][20][30];

Просто создайте новый массив, он инициализируется нулями. Это работает, если у вас есть одно место, которое содержит ссылку на массив. Не обращайте внимания на старый массив, он будет собран в мусор.

Если вы не хотите зависеть от такого поведения языка или не можете заменить все вхождения ссылок на старый массив, то вам следует используйте Arrays.fill () , как упоминал jjnguy:

for (int i = 0; i < cube.length; i++)
{
   for (int j = 0; j < cube[i].length; j++)
   {
      Arrays.fill(cube[i][j], 0);
   }
}

Arrays.fill, похоже, также использует цикл внутри, но в целом выглядит более элегантно.

14
ответ дан 3 December 2019 в 00:43
поделиться

Что ж, похоже, вы могли бы просто отказаться от старого массива и создать новый:

int size = 10;
cube = new int[size][size][size];
13
ответ дан 3 December 2019 в 00:43
поделиться
for (int i = 0; i < arr.length; i++){
    for (int j = 0; j < arr[i].length){
        Arrays.fill(arr[i][j], 0);
    }
}

Таким образом вы избавитесь от одного лишнего цикла, используя Arrays.fill ;

Или

arr = new double[arr.length][arr[0].length][arr[0][0].length];

К сожалению, это предполагает, что длина массива не менее > = 1 .

5
ответ дан 3 December 2019 в 00:43
поделиться

Несмотря на то, что является трехмерным массивом, наиболее удобочитаемое решение часто оказывается лучшим (наилучшее - это субъективное слово, вы должны были сказать лучшее в терминах некоторых свойство, и удобочитаемость обычно мой первый выбор).

Если бы действительно было только три элемента во внутреннем цикле, и вы хотели бы подчеркнуть, что есть три столбца, вы могли бы попробовать следующее:

for (int i = 0; i < n; i++) { 
    for (int j = 0; j < n; j++) { 
        cube[i][j][0] = 0; 
        cube[i][j][1] = 0; 
        cube[i][j][2] = 0; 
    }
}
2
ответ дан 3 December 2019 в 00:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: