快速获取 java 中两个浮点数列表总和的最大值和最大值索引
Get max and maxIndex of sum of two lists of floats in java fast
我正在尝试使用 "lightweight streams":
以比我在下面管理的更快的方式计算两个列表的最大和对
List<Float> pairsSum = new ArrayList<>();
// Get the list with all the sums
Stream.range(0, list1.size())
.forEach(i -> pairsSum.add(list1.get(i) + list2.get(i)));
// Get the index of the max pair
maxIndex = pairsSum.indexOf(Stream.of(pairsSum).max(Double::compare).orElse(0f));
List<Float> pairsSum = new ArrayList<>(repLeftForces.size());
// Get the list with all the sums
int maxIndex = -1;
float max = 0F;
for (int i =0; i < repLeftForces.size(); ++i) {
float sum = list1.get(i) + list2.get(i);
//pairsSum.add(sub);
if (maxIndex == -1 || sum > max) {
maxIndex = i;
max = sum;
}
}
实际上不需要 pairsSum 列表。但是使用的时候,实际尺寸是事先知道的。
因为有人想为最大值做一个 reduce,并额外接收 maxIndex,最好是经典循环而不是使用 Stream。
您可以通过映射流在一行中创建总和列表(为了易读性,我确实添加了换行符):
//made some example lists
List<Float> list1 = Arrays.asList(new Float[]{1F, 2F, 3F});
List<Float> list2 = Arrays.asList(new Float[]{2F, 3F, 4F});
// Get the list with all the sums
List<Float> sums = list1.stream()
.map( f -> (list2.get(list1.lastIndexOf(f)) + f ) )
.collect(Collectors.toList());
// Get the index of the max pair
int maxIndex = sums.indexOf(sums.stream().max(Float::compareTo).get());
只需流式传输第一个列表,然后 .map
它(映射类似于 foreach,但 returns 每个列表项的结果)。
地图上发生了什么:
对于每个项目,它会在列表 1 中找到当前值 f
的最高索引。这将是第一个列表中当前项目的索引。然后它在第二个列表中获取该索引的值。 list2.get(list1.lastIndexOf(f))
。所以现在你将当前值 f
添加到它。这样,对于列表 1 的全长,您将输出共享相同索引的两个值的总和。
然后您只需要 .collect
将它们放回列表中即可。
最后为了找到最大索引,我将采用与您完全相同的方法。
简短的解决方案是使用 IntStream
和 reduce()
方法:
int maxIndex = IntStream.range(0, list1.size())
.reduce((i1, i2) -> list1.get(i1) + list2.get(i1) < list1.get(i2) + list2.get(i2) ? i2 : i1)
.orElse(-1);
如果你想要索引,值和总和,你可以使用自定义 Result
class:
public static class Result {
private int index;
private float left;
private float right;
private float sum;
// constructor and getters
}
这样使用:
Result max = IntStream.range(0, list1.size())
.mapToObj(i -> new Result(i, list1.get(i), list2.get(i), list1.get(i) + list2.get(i)))
.max(Comparator.comparing(Result::getSum))
.orElse(null);
两种情况的时间复杂度都是O(n).
我正在尝试使用 "lightweight streams":
以比我在下面管理的更快的方式计算两个列表的最大和对 List<Float> pairsSum = new ArrayList<>();
// Get the list with all the sums
Stream.range(0, list1.size())
.forEach(i -> pairsSum.add(list1.get(i) + list2.get(i)));
// Get the index of the max pair
maxIndex = pairsSum.indexOf(Stream.of(pairsSum).max(Double::compare).orElse(0f));
List<Float> pairsSum = new ArrayList<>(repLeftForces.size());
// Get the list with all the sums
int maxIndex = -1;
float max = 0F;
for (int i =0; i < repLeftForces.size(); ++i) {
float sum = list1.get(i) + list2.get(i);
//pairsSum.add(sub);
if (maxIndex == -1 || sum > max) {
maxIndex = i;
max = sum;
}
}
实际上不需要 pairsSum 列表。但是使用的时候,实际尺寸是事先知道的。
因为有人想为最大值做一个 reduce,并额外接收 maxIndex,最好是经典循环而不是使用 Stream。
您可以通过映射流在一行中创建总和列表(为了易读性,我确实添加了换行符):
//made some example lists
List<Float> list1 = Arrays.asList(new Float[]{1F, 2F, 3F});
List<Float> list2 = Arrays.asList(new Float[]{2F, 3F, 4F});
// Get the list with all the sums
List<Float> sums = list1.stream()
.map( f -> (list2.get(list1.lastIndexOf(f)) + f ) )
.collect(Collectors.toList());
// Get the index of the max pair
int maxIndex = sums.indexOf(sums.stream().max(Float::compareTo).get());
只需流式传输第一个列表,然后 .map
它(映射类似于 foreach,但 returns 每个列表项的结果)。
地图上发生了什么:
对于每个项目,它会在列表 1 中找到当前值 f
的最高索引。这将是第一个列表中当前项目的索引。然后它在第二个列表中获取该索引的值。 list2.get(list1.lastIndexOf(f))
。所以现在你将当前值 f
添加到它。这样,对于列表 1 的全长,您将输出共享相同索引的两个值的总和。
然后您只需要 .collect
将它们放回列表中即可。
最后为了找到最大索引,我将采用与您完全相同的方法。
简短的解决方案是使用 IntStream
和 reduce()
方法:
int maxIndex = IntStream.range(0, list1.size())
.reduce((i1, i2) -> list1.get(i1) + list2.get(i1) < list1.get(i2) + list2.get(i2) ? i2 : i1)
.orElse(-1);
如果你想要索引,值和总和,你可以使用自定义 Result
class:
public static class Result {
private int index;
private float left;
private float right;
private float sum;
// constructor and getters
}
这样使用:
Result max = IntStream.range(0, list1.size())
.mapToObj(i -> new Result(i, list1.get(i), list2.get(i), list1.get(i) + list2.get(i)))
.max(Comparator.comparing(Result::getSum))
.orElse(null);
两种情况的时间复杂度都是O(n).