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

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

经过一番搔痒之后,我想出了这个(点数在一个数组中,当前部分是从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 ++中的序列运算符)。

感谢任何想法。 有更干净的方式吗?

这将是更可读的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 } } 

同样,“在xyz处划分”代码应该是函数调用,或者您可以获得剪切和粘贴的代码。

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

对于需要从任意点向外搜索的任何人来说,这是一个更通用的解决方案(在本例中,长度为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,