Assoziationskette programmieren

Panzenbaby

Mitglied
Hallo erst mal.

Da ich gerade an nem Beleg für Java arbeite und so ziemlich auf dem Schlauch stehe, dachte ich mir ich suche mir mal etwas Hilfe. Vielleicht hat ja jemand ne Idee wie ich weiter machen kann.

Hier die Aufgabe:
Die Klasse Assoziationen soll eine Menge von paarweisen Assoziationen speichern. Diese können jeweils mit der Methode
assoziationEintragen("Begriff1", "Begriff2");

eingetragen werden. Dabei führt ”Begriff1“ zu ”Begriff2“ (”Begriff1“ ! ”Begriff2“).
Es können zu einem Begriff mehrere Zeichenketten als zweiter Begriff eingetragen werden.
Im Weiteren sind wir vor allem an Assoziationsketten interessiert.
Wenn wir einen Satz an Assoziationen haben, können wir zu einem Ausgangsbegriff die Menge an Begriffen bestimmen,
die direkt mit dem ersten Begriff assoziiert sind. Wenn man zu jedem dieser Begriffe wieder die Assoziationen bestimmt, erhält man
die Menge der über einen Zwischenbegriff assoziierten Begriffe. Etc.
Zu diesen Menge interessiert uns die Anzahl der enthaltenen Begriffe:

anzahlAssoziierteBegriffe("Begriff", 1) // direkt assoziiert
anzahlAssoziierteBegriffe("Begriff", 2) // ueber Zwischenbegriff assoziiert

Und wir wollen auch für Begriffe überprüfen, ob sie in diese Menge enthalten sind:
istAssoziierterBegriff("Begriff1", 1, "Begriff2")

Beispiel:

Assoziationen assoz = new Assoziationen();
assoz.assoziationEintragen("Afrika", "Loewe");
assoz.assoziationEintragen("Afrika", "Elefant");
assoz.assoziationEintragen("Asien", "Elefant");
assoz.assoziationEintragen("Loewe", "Zoo");
assoz.assoziationEintragen("Elefant", "Zoo");
assoz.assoziationEintragen("Elefant", "Arbeitstier");
assoz.assoziationEintragen("Loewe", "Simba");


assoz.anzahlAssoziierteBegriffe("Afrika", 1)
Ergebnis: 2, weil die Menge fLoewe; Elefantg ist.

assoz.istAssoziierterBegriff("Afrika", 1, "Loewe")
Ergebnis: true

assoz.istAssoziierterBegriff("Afrika", 1, "Afrika")
Ergebnis: false

assoz.anzahlAssoziierteBegriffe("Asien", 1))
Ergebnis: 1, weil die Menge fElefantg ist.

assoz.anzahlAssoziierteBegriffe("Afrika", 2)
Ergebnis: 3, weil die Menge fArbeitstier; Simba; Zoog ist.

assoz.istAssoziierterBegriff("Afrika", 2, "Loewe")
Ergebnis: false

assoz.istAssoziierterBegriff("Afrika", 2, "Zoo")
Ergebnis: true

assoz.anzahlAssoziierteBegriffe("Afrika", 3)
Ergebnis: 0, weil die Menge ; ist.

Eingetragen werden die Assiziationen bei mir in eine HashMap, die als Key den ersten Begriff und als Wert eine LinkedListe mit dazugehörigen Assoziationen (2.Begriffe) hat.

Hier mal der Quellcode:

Java:
package belegdrei;
import java.util.*;

public class Assoziationen implements IAssoziationen {
	List<String> liste = new LinkedList<String>();
	Map<String, List> hm = new HashMap<String, List>();

	/* Der Speicher fuer die Assoziationen wird initisiert */
	public Assoziationen() {
		
	}
	
	/*
	 * Es wird ein Assoziationspaar eingetragen.
	 * Der Begriff *von* fuehrt zum Begriff *nach*
	 */
	public void assoziationEintragen(String von, String nach) {

		if(hm.get(von)==null)
		{
			liste=new LinkedList();
		}
		else
		{
			liste=hm.get(von);
		}
			liste.add(nach);
			hm.put(von, liste);
			System.out.println(von+" "+liste);
	}

Ich habe nun keine Ahnung wie ich anzahlAssoziierterBegriffe(String, Int) programmieren soll.

Ich weis es ist viel Text. Ich hoffe irgend jemand macht sich die Mühe ihn mal durch zu lesen und kann mir dann im Anschluss nen hilfreichen Tipp geben. Sitze jetzt schon 4h davor und habe mehrere Möglichkeiten versucht aber keine hat so wirklich zum gewünschten Ergebnis geführt.
Vielleicht habe ich mich ja schon im Ansatz selber ausgeschaltet?

Ich danke schon mal für die Antworten. :D
 

Noctarius

Top Contributor
Java:
Map<String, List<String>> assoziationen = new HashMap<String, List<String>>();

void add(String key, String value) {
    List<String> values = assoziationen.get(key);
    if (values == null)
        values = new ArrayList<String>();

    values.add(values);
    assoziationen.put(key, values);
}

int anzahl(String key) {
    List<String> values = assoziationen.get(key);

    if (values == null)
        return 0;

    return values.size();
}

So z.B.
 

Panzenbaby

Mitglied
Uhhh das ging ja schnell. Hätte ich nicht gedacht.

ganz großes Danke für deine Antwort. Ich werde es nachher gleich mal ausprobieren.
Muss jetzt aber leider erst mal Essen machen :)
 

Landei

Top Contributor
Sieht doch schon nicht schlecht aus.

Ich würde es so machen (ungetestet):
Java:
package belegdrei;
import java.util.*;
 
public class Assoziationen implements IAssoziationen {
    Map<String, List<String>> hm = new HashMap<String, List<String>>();
 
    /* Der Speicher fuer die Assoziationen wird initisiert */
    public Assoziationen() {
        
    }
    
    /*
     * Es wird ein Assoziationspaar eingetragen.
     * Der Begriff *von* fuehrt zum Begriff *nach*
     */
    public void assoziationEintragen(String von, String nach) {
        List<String> liste = hm.get(von);
        if(liste == null) {
            liste=new LinkedList<String>();
            hm.put(von, liste);
        }
        liste.add(nach);
        System.out.println(von+" "+liste);
    }

   public int anzahlAssoziierterBegriffe(String von, int schritte) {
       return assoziierteBegriff(von, schritte).size();  
   }

   public Set<String> assoziierteBegriffe(String von, int schritte) {
        if (schritte <= 0) {
            return new HashSet<String>();
        }
        List<String> liste = hm.get(von);
        if (liste == null) {
            return new HashSet<String>();
        }
        if (schritte == 1) {
           return new HashSet<String>(liste); //direkt assoziiert
        } else {
            Set<String> set = new HashSet<String>();
            for(String s : liste) {
                set.addAll(assoziierteBegriffe(s, schritte-1));
            } 
            return set;
        }
   }
}

Die Sets verwende ich, da ja offenbar Begriffe nicht doppelt gezählt werden dürfen (Afrika ist z.B. zweimal über zwei Schritte mit Zoo assoziiert, der Zoo soll aber nur einmal gezählt werden)
 

Panzenbaby

Mitglied
Die Sets verwende ich, da ja offenbar Begriffe nicht doppelt gezählt werden dürfen (Afrika ist z.B. zweimal über zwei Schritte mit Zoo assoziiert, der Zoo soll aber nur einmal gezählt werden)
Dir auch erst mal ein ganz großes DANKESCHÖN

Ahh auf die Idee Sets zu benutzen bin ich garnicht gekommen. Ja das hast du ganz richtig gesehen.
Ein Grund warum ich daran gescheitert bin ist gewesen, dass ich doppelte Assoziationen raus bekommen habe und die doppelte dann nicht weg bekommen habe. Dein entwurf sieht richtig gut aus.

Ich bin mal so frech und arbeite mit deinem Entwurf weiter, wenn du nichts dagegen hast.
Dann muss ich nur noch ein bischen ändern.
 
Zuletzt bearbeitet:

Landei

Top Contributor
Aber gerne!

Durch das Problem mit den Dopplungen wird es nicht viele andere Möglichkeiten geben, jedenfalls keine, die einfach alles rekursiv abzählt.
 

Panzenbaby

Mitglied
So ich habe jetzt deinen Entwurf übernommen. Hatte aber noch nicht ganz gestimmt. Hab nun eine kleine Änderung vorgenommen, sodass es nun so aussieht:

Java:
		if(iterationen==1)
		{
			Set<String> set=new HashSet<String>();
			set.addAll(liste);
			return set;
		}
		else
		{
			Set<String> set=new HashSet<String>();
			for(String s:liste)
			{
				set.addAll(assoziierteBegriffe(s,iterationen-1));
			}
			return set;
		}

Ich glaube das funktioniert jetzt so weit. Nun kann ich mich der nächsten Methode wenden. Noch mal Danke für die Hilfe. Wer weis wie lange ich gebraucht hätte um drauf zu kommen, dass ich ein Set benutzen muss :D

Edit:

Ich freu mir gerade ein 2. Loch in's Gesäß.

Wollte gerade ne Methode schreiben, welche überprüft ob ein Begriff eine x-te Assoziation eines anderen ist. Durch die tolle Vorarbeit musste ich nur einen Satz hinzufügen. Bin richtig Happy. Jetzt hab ich die Woche Ruhe :D
 
Zuletzt bearbeitet:

Neue Themen


Oben