Перемещение чисел в строке массива

#java

Вопрос:

У меня возникают проблемы с визуализацией того, что происходит, когда у меня, например, есть строка чисел [1,2,3,4,5], и я либо хочу переместить эти числа в начало строки, либо в конец строки.

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

Фрагмент кода:

 void addCoordinateRowFront(CoordinateRow rowOfCoordinates) {   for(int j = rowOfCoordinates.numberOfElements; j gt; 0; j--) {   for(int i = numberOfElements; i gt; 0; i--) {   newCoordinateArray[i] = newCoordinateArray[i-1];   }  newCoordinateArray[0] = rowOfCoordinates.newCoordinateArray[j-1];   numberOfElements  ;  }   }  }  

Но я все еще не совсем понимаю, что происходит.

Например, если у меня есть строка [1,2,3,4,5], каков результат, если я добавлю эти числа в начало или в конец строки?

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

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

2. Если я правильно записываю это, то, например, если я перенесу эти числа в начало строки, то в конечном итоге я снова получу [1,2,3,4,5], верно?

3. Вы предоставляете недостаточно информации. Откуда ты взял newCoordinateArray ? Как он инициализируется (потому что, если он пустой, в строке нет смысла newCoordinateArray[i] = newCoordinateArray[i-1]; )? Какой результат вы ожидаете получить?

Ответ №1:

newCoordinateArray[i] = newCoordinateArray[i-1]; в основном это смещение элементов назад, т. е. элемент с индексом 2 получит значение из индекса 1, затем индекс 1 получит значение из индекса 0. Наконец, индекс 0 получит новое значение.

Внутренняя петля

Это означает, что ваш внутренний цикл превратился [1,2,3,4,5] бы в [1,1,2,3,4] , если бы он был правильным:

  • a[4] = a[3] -gt; значение в индексе 4 будет значением индекса 3, результатом будет [1,2,3,4,4]
  • a[3] = a[2] -gt; [1,2,3,3,4]
  • a[2] = a[1] -gt; [1,2,2,3,4]
  • a[1] = a[0] -gt; [1,1,2,3,4]

Если вы посмотрите на пример, вы сможете обнаружить ошибку во внутреннем цикле:

int i = numberOfElements будет означать i = 5 , если numberOfElements на самом деле означает rowOfCoordinates.numberOfElements (что в примере будет равно 5). Однако a[5] = ... это приведет ArrayOutOfBoundsException к тому, что самый высокий индекс в массиве из 5 элементов равен 4.

Внешняя петля

Ваш внешний цикл переходит в индекс 0, начиная с последнего элемента ( a[0] = a[j-1] ). Это означает, что после первого запуска внутреннего цикла у вас есть [1,1,2,3,4] и теперь a[0] = a[4] будет результат [4,1,2,3,4] .

Теперь давайте рассмотрим другие итерации внешнего цикла:

  • j = 4 -gt; результат внутреннего цикла: gt; [4,4,1,2,3] , a[0] = a[3] приводит к [2,4,1,2,3] (значение a[3] равно 2)
  • j = 3 -gt; результат внутреннего цикла: gt; [2,2,4,1,2] , a[0] = a[2] приводит к [4,2,4,1,2] (значение a[2] равно 4)
  • j = 2 -gt; результат внутреннего цикла: gt; [4,4,2,4,1] , a[0] = a[1] приводит к [4,4,2,4,1] (значение a[1] равно 4)
  • j = 1 -gt; результат внутреннего цикла: gt; [4,4,4,2,4] , a[0] = a[0] ничего не меняет, поэтому конечным результатом будет [4,4,4,2,4]

Как сдвинуться с места

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

 //replace 1st element  int replacedIndex = dir;  int replacedValue = array[replacedIndex];  array[replacedIndex] = array[0];    //replace all other elements  for( int i = 1; i lt; array.length; i  ) {  replacedIndex = (replacedIndex   dir) % array.length;   int temp = array[replacedIndex];  array[replacedIndex] = replacedValue;  replacedValue = temp;  }  

Это означает следующее:

Вы перемещаете первый элемент в его новое положение, которое заменяет другой элемент. Таким образом, вы отслеживаете замененный элемент и его индекс. Цикл теперь перемещает замененный элемент, который заменяет другой, о котором позаботится следующая итерация.

Таким образом,смещение [A,B,C,D, E] на 2 означало бы:

  • Первоначально переместите A из индекса 0 в индекс 2, поэтому C будет заменен. Результат: [A,B,A,D,E].
  • C будет перенесен из индекса 2 в индекс 4: [A,B,A,D,C]
  • E будет смещен с индекса 4 на индекс 1 (обтекание): [A,E,A,D,C]
  • B будет перенесен из индекса 1 в индекс 3: [A,E,A,B,C]
  • D будет смещен с индекса 3 на индекс 0 (обтекание): [D,E,A,B,C]

Оператор по модулю также может использоваться для обеспечения больших сдвигов, которые в основном возвращаются в диапазон, т. Е. Смещение массива из 4 элементов на 13 равно смещению на 1 (13% 4 = 1).

Отрицательные сдвиги могут быть поддержаны путем приведения сдвига в положительный диапазон путем добавления длины, т. Е. При наличии массива из 5 элементов сдвиг на -1 (1 влево) совпадает со сдвигом на 4 (4 вправо).

Так что вы могли бы сделать это с самого начала:

 //copy the initial parameter to keep the original value int dir = direction;  //shift direction into a positive range while( dir lt; 0) {  dir  = array.length; }  //bring any out-of-range direction back into range dir %= array.length;