У меня где-то пересеклись провода (или я не выспался). Мне нужен двусторонний цикл, и мой текущий код просто безобразен.
Проблема: я бегу по линейному типу данных, используя индекс. У меня есть стартовый индекс, скажем, 120. Я хочу бегать попеременно в обоих направлениях.
Пример:
120.121.119.122.118.123.117, ...
У меня есть критерий остановки, который необходимо соблюдать для каждого направления в отдельности. Если это встречается для одного направления, я только хочу бежать в другом направлении, если оба встречаются, мне нужно выйти из цикла. Кроме того, мне нужно остановиться, если следующий индекс недопустим (конец структуры данных, скажем, меньше 0 или больше 200).
Пример: Остановка выполнения на 116 назад и на 130 вперед:
120.121.119.122.118.123.117.124.116 (перерыв), 125.126.127.128.129.130.
Сначала бежать в одном направлении, затем, к сожалению, другое.
Мой текущий код просто ужасен. Много строк без какого-либо «производительного» кода. Только логика итерации:
int start_idx = 120;
int forward_idx = start_idx;
int backward_idx = start_idx;
bool next_step_forward = true; //should next step be forward or backward?
int cur_idx;
while(backward_idx >= 0 || forward_idx >= 0)
{
if(next_step_forward //if we should step forward
&& forward_idx >= 0) //and we still can step forward
{
cur_idx = ++forward_idx;
if(forward_idx >= 200) //200 is fictive "max index"
{
next_step_forward = false;
forward_idx = -1; //end of data reached, no more stepping forward
continue;
}
if(backward_idx >= 0)
{
next_step_forward = false;
}
}
else if(!next_step_forward
&& backward_idx >= 0)
{
cur_idx = --backward_idx;
if(backward_idx < 0) //beginning of data reached, no more stepping backward
{
next_step_forward = true;
continue;
}
if(forward_idx >= 0)
{
next_step_forward = true;
}
}
else
{
next_step_forward = !next_step_forward; //ever hit?, just security case
continue;
}
//loop body
//do something with cur_idx here
if(stoppingCriterionMet())
{
if(cur_idx > start_idx)
{ //this was a forward step, stop forward stepping
forward_idx = -1;
}
else
{ //this was backward step, stop backward stepping
backward_idx = -1;
}
}
}
Я что-то упустил? Любые намеки приветствуются. Спасибо.
Редактировать 1: Есть много очень хороших ответов, которые помещают «сделать что-то с cur_idx» в отдельную функцию. Хотя это идеальная идея для моего вопроса, я предпочитаю размещать итеративный код в другом месте и оставлять там производительный код. У меня длинный алгоритм, и я хочу разделить его после завершения, чтобы минимизировать работу по перестановке.