从中间向外循环数组的算法?

时间:2011-07-26 23:52:54

标签: java c++ c algorithm

我正在研究一种分而治之的算法(事实上,这种算法可以对多个输入点进行曲线拟合)。对于“除法”部分,我需要计算每个点的误差项,如果误差超过给定的阈值,我希望在该点分割曲线并分别处理输入的左右部分。一个简单的循环就可以了;但是对我来说,从当前部分的中间开始并向外工作将是有利的。 (澄清一下:如果我找到一个误差太大的点,我会递归调用并为左右两部分生成单独的曲线 - 如果所有点都在阈值范围内,那么我的曲线适合我返回)。 p>

经过一番搔痒之后,我想出了这个(点数在一个数组中,当前部分从startIndexendIndex包括在内):

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 / C ++中的序列运算符)。

任何想法都表示感谢。有更清洁的方式吗?

3 个答案:

答案 0 :(得分:14)

这将更具可读性imho

for (int q=0; q < steps; q++) {
   int index = i + ( q% 2 == 0 ? q/2 : -(q/2+1)); //index lookup here
}

答案 1 :(得分:1)

如果您的超出错误检查器很简单(例如函数调用),最明显的是写:

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
     }
}

再次,“在xyz处划分”代码应该是一个函数调用,或者你得到了切割&amp;粘贴的代码。

(我没有仔细考虑角落情况和一对一错误,所以当我= = mid时要小心,但是你得到了照片。)

答案 2 :(得分:0)

对于需要从任意点向外搜索的任何人(在此示例中,长度为7的数组中的单元格[6]),这是一个更通用的解决方案。

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,