Lambda-Funktion bei Binärbäumen

Hallo zusammen,

kann mir jemand sagen wie diese Aufgaben funktionieren?

Vielen Dank!
 

Anhänge

  • Bildschirmfoto 2016-10-08 um 14.13.03.JPG
    Bildschirmfoto 2016-10-08 um 14.13.03.JPG
    308 KB · Aufrufe: 35
  • Bildschirmfoto 2016-10-08 um 14.13.11.JPG
    Bildschirmfoto 2016-10-08 um 14.13.11.JPG
    89,7 KB · Aufrufe: 28
Bei Aufgabe 2 berechnest du die Lösung mit "myTree.each((a,v) -> Math.max(a,v))". Und bei 3 mit "myTree.each((a,v) -> a+v)/myTree.count()".
 
Sorry aber die Lösungen sind falsch.
Wenn sich aus der Aufgabenstellung folgende Implementierung für each ableiten lässt:
Java:
public double each(TreeWalkerInterface treeWalkerInterface) {
    double aggregated = 0;
    for (Double value : wrappedTree) {
        aggregated += treeWalkerInterface.apply(aggregated, value);
    }
    return aggregated;
}
kommt man für das Maximum mit Math.max allein nicht aus, da sich a ja erhöht!
Folgender Lambda Ausdruck ist zielführend:
Java:
(a, v) -> Math.max(a,v) - a
Hiermit lässt man aggregated, also die Summe, nie höher als die im jeweiligen Durchlauf höhere der beiden Zahlen a und v werden.
Die Lösung für 3. kannst du im Code nachvollziehen.
Wie folgt getestet:
Java:
package treelambda;

import java.util.TreeSet;

public class Tree {

    private TreeSet<Double> wrappedTree;

    public Tree() {
        wrappedTree = new TreeSet<>();
    }

    public void add(double value) {
        wrappedTree.add(value);
    }

    public int count() {
        return wrappedTree.size();
    }

    public double each(TreeWalkerInterface treeWalkerInterface) {
        double aggregated = 0;
        for (Double value : wrappedTree) {
            aggregated += treeWalkerInterface.apply(aggregated, value);
        }
        return aggregated;
    }

    public TreeSet<Double> getWrappedTree() {
        return wrappedTree;
    }
}
package treelambda;

@FunctionalInterface
public interface TreeWalkerInterface {
    double apply(double aggrgated, double nodeValue);
}
package treelambda;

import org.junit.Before;
import org.junit.Test;

import java.util.DoubleSummaryStatistics;
import java.util.stream.Collectors;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

public class TreeTest {

    private Tree tree;
    private DoubleSummaryStatistics stats;

    @Before
    public void setUp() {
        this.tree = new Tree();
        tree.add(13);
        tree.add(10.5);
        tree.add(8);
        tree.add(11);
        stats = tree.getWrappedTree().stream().collect(Collectors.summarizingDouble(Double::doubleValue));
    }

    @Test
    public void testMax() {
        double max = tree.each((a, v) -> Math.max(a,v) - a);
        assertThat(max, is(stats.getMax()));
    }

    @Test
    public void testAvg() {
        double avg = tree.each((a, v) -> v) / tree.count();
        assertThat(avg, is(stats.getAverage()));
    }

}
Für 1. natürlich einfach add aufrufen.
 
Zuletzt bearbeitet:
Dort steht aber der "aggregierte Wert" mit der Randbedingung für den ersten Aufruf. Aggregiert bedeutet zusammengefasst, was für Zahlen im einfachsten Fall aufsummieren impliziert.
 
Zuletzt bearbeitet:
"aggregierte Wert" ist erstmal nur eine Bezeichnung für den Wert. Das kann vieles Bedeuten. In diesem Fall ist mit aggregieren gemeint, dass aus allen Werten des Baumes, durch die Anwendung des Lamda Ausdruckes, ein einzelner Wert berechnet wird.
 
Ok ich verstehe deinen Ansatz. Aber aggregiert deutet für mich stark auf summieren hin, weswegen ich die each Methode anders als du angenommen habe und wir somit auf 2 Lösungsansätze durch Unklarheiten in der Aufgabenstellung kommen.

//Edit: wobei der Satz "Bei allen folgenden Aufrufen den zuletzt durch apply zurückgegebenen Wert." doch summieren widerspricht.
Deine Lösungen kann ich mit neuer Ansicht der each Methode bestätigen.
 
wieso ziehst du dann bei der 2. -a ab?
Das habe ich doch bereits beschrieben. Weiter: a wird ja für jeden Aufruf mitgegeben und dient somit als "Puffer" um Informationen zwischen 2 Aufrufen zu teilen. In dem Fall ist die Information die zum Aufruf bekannte höchste Zahl. Mit Math.max ermitte ich die höhere der Beiden Zahlen und gebe die Differenz zur alten höheren Zahl zurück. Die die zurückgegebene Differenz des Lambdas wird ja in aggregated aufsummiert. Also summiere ich entweder 0 auf oder v-a auf. Ich kann es leider schlecht erklären. Einfach im Debugger mal nachvollziehen.
und wie würde dann die Lösung für die 3 aussehen?
siehe
Die Lösung für 3. kannst du im Code nachvollziehen.
Hast du die Antwort überhaupt gelesen? 😕
 
Zuletzt bearbeitet:
Mir wird bei der 3. nicht klar was der Ausdruck "(a, v)-> v)/ tree.count() "macht?
Du musst beachten, dass ich die Aufgabe anders als DrZoidberg verstanden habe und vermutlich falsch: Ich ging ja davon aus, dass aggregated die Summe sein soll.
Somit gebe ich bloß den nodeValue v zurück, der in der each aufsummiert wird. each gibt mit dieser Lamda also die Summe zurück! Dann teile ich durch die Anzahl der nodes, denn so bildet man nun mal den Durchschnitt.

Falls das Klausuraufgaben sind musst du dich unbedingt damit beschäftigen und es verstehen.
 

Zurück
Oben