J'essaie de calculer la somme maximale de deux listes avec un moyen plus rapide que ce que j'ai géré ci-dessous, en utilisant "flux légers" :
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));
3 Réponses :
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; } } The pairsSum list is not needed actually. But when used, the actual size is known in advance.As one wants to do a reduce too for a maximum, and receive additionally the maxIndex, best would be a classical loop instead of using a Stream.
Vous pouvez créer la liste des sommes sur une ligne en mappant les flux (j'ai ajouté des sauts de ligne pour la lisibilité):
//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());
Il suffit de diffuser la première liste, et .map
it (la carte est comme un foreach mais renvoie un résultat pour chaque élément de la liste).
Que se passe-t-il sur la carte:
pour chaque élément, il trouve l'index le plus élevé pour la valeur actuelle f
dans la liste 1. Ce sera l'index de l'élément actuel dans la première liste. Ensuite, il obtient la valeur de cet index dans la deuxième liste. list2.get (list1.lastIndexOf (f))
. Alors maintenant, vous ajoutez la valeur actuelle f
à cela. De cette façon, pour toute la longueur de la liste 1, vous sortez la somme des deux valeurs qui partagent le même index.
Il vous suffit ensuite de les .collect
de nouveau dans un list.
Enfin, pour trouver l'index max, j'adopterais exactement la même approche que vous.
Cette solution n'est pas plus rapide que la solution fournie par OP, car List.indexOf ()
a une complexité temporelle de O (n). Votre solution a donc une complexité temporelle de _O (n²) .
La solution courte consiste à utiliser un IntStream
et la méthode reduction ()
:
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);
Si vous voulez l'index, les deux valeurs et la somme, vous pouvez utiliser une classe Result
personnalisée:
public static class Result { private int index; private float left; private float right; private float sum; // constructor and getters }
Utilisez-la comme ceci:
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);
Et où est le problème ou la question?
Peut-être que la liste pairesSum n'est pas nécessaire et que le calcul de la somme et du maximum pourrait être fait à la volée, mais je ne pouvais pas le comprendre, donc je demande généralement une optimisation sur le code ci-dessus.
Double possible de stackoverflow.com/questions/30730861/... ?
@DominicFischer C'est à peu près un tableau, pas la somme de deux tableaux
Oups, mais vous pouvez toujours adapter cette solution à la vôtre.