2016-10-01 101 views
0

我想执行Newton interpolation formula。也许这给了下面的文字更有意义。组合列表中的相邻元素

我找一个列表的功能,结合在列表中每两个相邻的新的价值。它应该非常快,并且(如果可能)不涉及创建新列表。我想连续多次执行下面描述的缩小操作,但是要获取其中的一些数据。

Before: a b c d 
     \/\/\/
After: ab bc cd 

它被组合的二元函数应该可以自由切换。

到目前为止,我想出了这样的事情(但阵列):

double[] before = {4, 3, 7, 1}; 

while(before.length > 1){ 
    double[] after = new double[before.length - 1]; 

    for (int i = 0; i < after.length; i++){ 
     after[i] = chosenBinaryFunction(before[i], before[i+1]); 
    } 

    //store after[0] 

    before = after; 
} 

回答“没有比你做了什么更好的方式”是可以接受的。在这种情况下,请提供如何改进方法的提示(例如,避免在while中创建大量新列表,可能的快捷方式...)。

回答

0

肯定可以避免创建新的数组。解决的办法很简单,因为一旦它使用了第二次计算,因此算法可以覆盖其左操作数不再使用:

double[] before = {4, 3, 7, 1}; 
int length = before.length; 

while (length > 1) { 
    --length; 
    for (int i = 0; i < length; i++){ 
     before[i] = chosenBinaryFunction(before[i], before[i+1]); 
    } 
} 
0

如果你真的希望能够选择一个二元函数,看BinaryOperator 。具体为BinaryOperator<double>。用这种方法,加入这一行:

BinaryOperator<double> b = ... 

然后你就可以改变这一行:

after[i] = chosenBinaryFunction(before[i], before[i+1]); 

要这样:

after[i] = bo.apply(before[i], before[i+1]) 

另外,我认为你创建一个新的阵列是浪费每次你经过循环。我会做更多的东西像这样(完整版):

double newtonInterpolation(double[] before, BinaryOperator<double> bo) { 
    double[] after = new double[before.length - 1] // Creates array ONE time 

    for (int i = 0; i < after.length; i++) { 
     after[i] = bo.apply(before[i], before[i + 1]) // Uses fancy BinaryOperator 
    } 

    return after 
} 

声明:我没有测试此代码还,所以它提供的“原样”,但我希望这有助于!

0

你几乎得到它的数组。 您的for循环的唯一条件应该是i < after.length-1否则,当循环索引(i)到达数组中的最后一个位置时,您将获得IndexOutOfBounds异常,因为您会正在调用数组中的i + 1元素,该元素不存在。

因此,对于列表中的上述内容,您可以在(例如让它成为ArrayList)之前从列表开始,它具有a,b,c,d,e,f,g,的元素。 ... 这里是你怎么做:

ArrayList<Integer> after; 
while(before.size() > 1){ 
    after = new ArrayList<>(); 
    for(int i=0;i<(before.size()-1);i++){ 
     int joinedValue = joinValuesFunction(before.get(i),before.get(i+1)); 
     after.add(joinedValue); 
    } 
    before = after; 
} 

可避免重用以前列表创建新列表,如果你会用后的元素尽快移除和更换的元素前你会计算它们。例如:

while(before.size() > 1){ 
    for(int i=0;i<(before.size()-1);i++){ 
     int joinedValue = joinValuesFunction(before.get(i),before.get(i+1)); 
     before.remove(i); //Remove the element at position i 
     before.add(i,joinedValue); //Add the joined value at position i. This will shift all elements of this ArrayList (from i to before.getSize()-1) to the right by one position. 
    } 
    before.remove(before.size()-1); //Removes the last element 
} 

不知道哪个更快。尝试使用两种方法并让我们知道。

希望这会有所帮助。