合并列表中的相邻元素

时间:2016-10-01 22:57:03

标签: java list

我想实现Newton interpolation formula。也许这使得以下文字更有意义。

我寻找一个List-Function,它将列表中的每两个邻居组合成一个新值。它应该非常快,并且(如果可能的话)不涉及创建新列表。我想连续多次执行下面描述的缩减,但是抓住其中的一些数据。

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

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

3 个答案:

答案 0 :(得分: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]);
     }
}

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

免责声明:我还没有测试过这段代码,所以提供了#34; as-is&#34;,但我希望这有帮助!

答案 2 :(得分:0)

你几乎得到了数组。 唯一的问题是你的for循环的条件应该是 i&lt; 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;
}

您可以通过重复使用之前的列表来避免创建新列表,如果您想在之后删除之前的元素并将其替换为之后的元素。 d计算它们。例如:

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
}

不确定哪个更快。尝试两种方法的时间,让我们知道。

希望这有帮助。