Велоспорт между элементом выше и ниже текущего элемента массива


Название отстой, но это действительно очень просто - дан массив а начальный элемент цикла от одного элемента сверху, снизу, потом два сверху и снизу стартовый элемент. Например:

Start: 5
5 > 6 > 4 > 7 > 3 > 8 > 2 ... 

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

Start: 2
2 > 3 > 1 > 4 > 0 > 5 > 6 > 7 ...

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

var distance = 0;

while ((currentHeight + this.heights[index]) < height) {
    sections.push(index);
    currentHeight += this.heights[index];

    distance = -distance + (distance >= 0 ? -1 : 1);
    index += distance;

    if (index < 0 || index >= this.heights.length) {
        distance = -distance + (distance >= 0 ? -1 : 1);
        index += distance;
    }
}

расстояние - это расстояние от начального пункта, индекс содержит текущую позицию. Код циклов с этих двух строк:

distance = -distance + (distance >= 0 ? -1 : 1);
index += distance;

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



352
4
задан 12 марта 2011 в 05:03 Источник Поделиться
Комментарии
3 ответа

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

Ваша попытка была для расчета индекса от предыдущего индекса. Вместо этого я создал функцию, которая сопоставляется с увеличением индекса (0, 1, 2, 3, 4,...) к целям (0, 1, -1, 2, -2,...). Поэтому мы ищем для функции ф(я) , где ф(0) = 0, Ф(1) = 1, Ф(2) = -1, Ф(3) = 2и т. д.

Я придумал: (я % 2 ? 1 : -1) * математика.пол( (я+1) / 2 ).

Теперь вам просто необходимо условие, чтобы пропустить новых индексов за пределы массива. Я придумал следующее:

var yourArray = new Array(10);
var start = 2;

var i = 0;
var max = yourArray.length;

while (max) {
var newI = (i%2?1:-1) * Math.floor((i+1)/2) + start;
if (newI >= 0 && newI < yourArray.length) {
document.write( newI + "<br>");
// do something with yourArray[newI];
max--;
}
i++;
}

Моя проблема, как решить, когда, чтобы остановить цикл. Сейчас я просто петли в два раза длину массива. Которые обычно приводят к излишней итераций, но, возможно, кто-то может придумать лучшее решение, или есть, может быть, состояние, которое приходит из вашего приложения. Обновление: нашел решение.

5
ответ дан 12 марта 2011 в 07:03 Источник Поделиться

Последовательность, которую вы описываете +1, -2, +3, -4, +5, -6, ... так что моя идея заключалась в том, чтобы держать два мутировавших значения

var step = 0;
var direction = 1;

где шаг увеличивается, а направление меняется на противоположное

step++;
direction *= -1;

и они применяются к текущему индексу

index += step * direction;

каждый раз через петлю. В противном случае код выглядит так же, как решение Ротора по (+1 по формуле, кстати).

var yourArray = new Array(10);
var index = 2;

var step = 0;
var direction = 1;
var max = yourArray.length;

while (max) {
if (index >= 0 && index < yourArray.length) {
document.write( index + "<br>");
// do something with yourArray[index];
max--;
}
step++;
direction *= -1;
index += step * direction;
}

4
ответ дан 12 марта 2011 в 10:03 Источник Поделиться

Гораздо более легкий способ сделать это:

var myarray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
var start = 8, step = 1, current = start+step;
while (myarray[current]) {
console.log(myarray[current]);
current = (current>start) ? start-(current-start)-1 : start+(start-current);
}

=> 10 ,7 ,11 ,6 ,12 ,5 ,13 ,4 ,14 ,3 ,15 ,2

1
ответ дан 1 апреля 2011 в 09:04 Источник Поделиться