Ответ 1
Это было бы более читаемым imho
for (int q=0; q < steps; q++) {
int index = i + ( q% 2 == 0 ? q/2 : -(q/2+1)); //index lookup here
}
Изменить: реализована ошибка в поиске индекса
Я работаю над алгоритмом "разделяй и властвуй" (на самом деле, тот, который наводит кривые на несколько входных точек). Для части "divide" мне нужно рассчитать коэффициент ошибки для каждой точки, и если ошибка превышает заданный порог, я хочу разбить кривую в этой точке и обработать левый и правый участки входа отдельно. Простая петля делает трюк; но мне было бы полезно начать в середине текущего раздела и работать наружу. (Чтобы уточнить: если я нахожу точку, чья ошибка слишком велика, я рекурсивно вызываю и генерирую отдельные кривые для левого и правого секций - если все точки находятся в пределах порога, тогда моя кривая подходит и я возвращаюсь).
После небольшого поцарапания головы я придумал это (точки находятся в массиве, а текущий раздел от startIndex
до endIndex
включительно):
int steps = (endIndex+1-startIndex);
int i = (startIndex+endIndex)>>1;
int stepdir = 1;
for(int q=0; q<steps; q++, i+=stepdir*q, stepdir=-stepdir)
{
// test point i here and return early if error exceeds threshold
}
Другими словами, начиная с середины, пройдите один указатель вперед, два назад, три вперед, четыре назад... Это работает, и я уверен, что он эффективен, но мне кажется, что должен быть более чистый способ для этого, в частности, мне пришлось проверить спецификацию языка Java, чтобы убедиться, что операторы в выражении for update действительно оценивали последовательно (хотя это не оператор последовательности, как в C/С++).
Любые идеи с благодарностью оценили. Есть ли более чистый способ?
Это было бы более читаемым imho
for (int q=0; q < steps; q++) {
int index = i + ( q% 2 == 0 ? q/2 : -(q/2+1)); //index lookup here
}
Изменить: реализована ошибка в поиске индекса
Если ваш избыточный контролер ошибок прост (например, вызов функции), самая ясная вещь - написать:
int mid = npoints / 2;
for (int i = 0; i <= mid; i++) {
if( excess_error(mid + i + 1) ) {
// divide at mid + i + 1
} else if excess_error(mid - i) {
// divide at mid - i
}
}
Снова код "divide at xyz" должен быть вызовом функции, или вы получаете вырезанный и вставленный код.
(Я не очень тщательно думал об угловых случаях и ошибках "один за другим", поэтому будьте осторожны, когда я == mid, но вы получите изображение.)
Здесь более общее решение для тех, кому нужно искать наружу из произвольной точки (в этом примере ячейка [6]
в массиве длиной 7).
int arraySize = 7;
int start = 6;
for (int i=0; i < arraySize; i++) {
int index = (start+((i%2==0)?i/2:arraySize-(i+1)/2))%arraySize;
print(index+",");
}
exit();
Печатает 6,5,0,4,1,3,2,