#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;