Überschreiben von Variablen bei rekursivem Funktionsaufruf

koche82

Mitglied
Hallo Community,

ich benötige mal wieder eure Hilfe. Momentan arbeite ich an einer Analyse, die mir aus einem Mannschaftsteil die Kombination ermittelt, welche in der Vergangenheit am erfolgreichsten war. Der Mannschaftsteil besteht aus drei Spielern (3 Torhüter) und aus der Anzahl der möglichen Törhüter (knapp 60) habe ich 34220 mögliche Kombinationen ermittelt.

Bei der Ermittlung dieser Kombinationen versuche ich mir die Gesamtpunktezahl zu merken und zum Schluß das erfolgreichste Torhüter-Team auszugeben.

Jetzt das Problem:
Bei der Ermittlung dieser Kombinationen rufe ich eine Funktion rekursiv auf (Den Sourcecode habe ich mir aus einem 6 aus 49 Beispiel abgekuckt). Offensichtlich ist dieser rekursive Aufruf daran schuld, dass mir die Variable mit dem "besten Team" überschrieben wird, welcher ich vorher das beste Team zugewiesen habe. Anbei das Code Beispiel

Java:
import java.util.ArrayList;

import com.xyz.jsoupexample.Spieler;
import com.xyz.jsoupexample.Team;

public class TorhueterGenerator implements Runnable {
	private Team torhueterTeam;
	private int anzTeamTorhueter;
	private ArrayList<Spieler> spielerList = new ArrayList<Spieler>();
	private Team bestTeam;
	private int hoechstePunktzahl = 0;
	private int besteKombination = 0;

	int counter = 1;

	public TorhueterGenerator(int anzTeamTorhueter,
			ArrayList<Spieler> spielerList) {
		this.spielerList = spielerList;
		this.anzTeamTorhueter = anzTeamTorhueter;
		this.torhueterTeam = new Team(anzTeamTorhueter);
		this.bestTeam = new Team(anzTeamTorhueter);
	}

	private synchronized void print() {
		System.out.println();

		Spieler[] spieler = torhueterTeam.getSpielerListe();

		for (Spieler keeper : spieler) {
			System.out.print(keeper.getName() + " ");
		}

		System.out.println("Der Gesamtmarktwert: "
				+ torhueterTeam.getGesamtPunktzahl());

		System.out.println("Kombination " + counter++ + " Gesamtpunktzahl: "
				+ torhueterTeam.getGesamtPunktzahl());

		if (bestTeam.getGesamtPunktzahl() < torhueterTeam
				.getGesamtPunktzahl()) {
			hoechstePunktzahl = torhueterTeam.getGesamtPunktzahl();
			bestTeam.setSpielerListe(torhueterTeam.getSpielerListe());

		}
		for (Spieler keeper : bestTeam.getSpielerListe()) {
			System.out.print(keeper.getName() + " (Bestes Team) ");
		}

	}

	private void berechneTeamKombination(int offenePositionen, int start) {
		if (offenePositionen > 0) {
			for (int i = start; i < spielerList.size(); i++) {
				torhueterTeam.getSpielerListe()[torhueterTeam.getSpielerListe().length
						- offenePositionen] = this.spielerList.get(i);
				berechneTeamKombination(offenePositionen - 1, i + 1);
			}
		} else {
			print();
		}

	}

	public void run() {
		berechneTeamKombination(anzTeamTorhueter, 0);
	}
}

Ich habe den SourceCode gedebuggt und beim Aufruf des Abschnittes
Java:
torhueterTeam.getSpielerListe()[torhueterTeam.getSpielerListe().length
						- offenePositionen] = this.spielerList.get(i);

wird die Variable bestTeam überschrieben. Habt ihr eine Idee, warum das so ist? Selbst wenn ich der Funktion print() eine Kopie der Variable "torhueterTeam" übergebe, ändert sich nichts am Ergebnis

Anbei die Ausgabe der letzten print()-Aufrufe:

Grün Mielitz Wolf Der Gesamtmarktwert: 56
Kombination 34218 Gesamtpunktzahl: 56
Grün (Bestes Team) Mielitz (Bestes Team) Wolf (Bestes Team) Die hoechste Punktzahl: 56

Grün Strebinger Wolf Der Gesamtmarktwert: 8
Kombination 34219 Gesamtpunktzahl: 8
Grün (Bestes Team) Strebinger (Bestes Team) Wolf (Bestes Team) Die hoechste Punktzahl: 8

Mielitz Strebinger Wolf Der Gesamtmarktwert: 56
Kombination 34220 Gesamtpunktzahl: 56
Mielitz (Bestes Team) Strebinger (Bestes Team) Wolf (Bestes Team) Die hoechste Punktzahl: 56
 
Es wird nicht das Team überschrieben, sondern die Spielerliste, da du in beiden Teams die selbe Spielerliste-Referenz verwendest.

Wenn es nicht wirklich die IDENTISCHE Liste sein soll, die du setzt, dann erstelle beim setzen der Liste eine ganz neue. Etwa so

Java:
#.setSpielerListe(new ArrayList(#.getSpielerListe))

EDIT: Habs nur überflogen, ich hoffe das stimtm überhaupt, was ich da sage ... aber das Verhalten, das du beschreibst, deuett darauf hn.
 
Zuletzt bearbeitet:
Hier mal ein paar Tips, die das Schreiben von komplexen Programmen stark vereinfachen und die Fehleranfälligkeit reduzieren.

Alle Variablen, die man lokal definieren kann, sollte man nicht zu Instanzvariablen machen. In deinem Fall benötigst du nur zwei Instanzvariablen - anzTeamTorhueter und spielerList. Der Rest kann lokal (also innerhalb einer Methode) definiert werden.

Pack nicht zu viel in eine Methode. print() und bestimmeBestesTeam() sollten zwei verschiedene Methoden sein. berechneTeamKombination() sollte lediglich die Team Kombinationen berechen, aber nicht print aufrufen.

Wenn ein Objekt eine veränderbare Datenstruktur enthält, z.B. ein Array, dann sollte es keine Methode geben, die dieses Array zurückliefert. Denn ein Objekt sollte immer die volle Kontrolle über den eigenen Zustand haben. Gib also immer nur eine Kopie des Arrays zurück.
 

Neue Themen


Zurück
Oben