2016-10-01 134 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 
} 

不知道哪個更快。嘗試使用兩種方法並讓我們知道。

希望這會有所幫助。