vergleich von arrays (benötige Hilfe/Denkanstoß)

javaang

Mitglied
Hallo ich benötige Hilfe bei meiner letzten Aufgabe, da ich nicht so wirklich was wie ich das angehen soll von der Logic her. Und zwar habe ich mehrere Kunden als array und ein Produkte array, sowie ein 2d array mit boolean werten.

Nun zu meiner Aufgabe ich soll herausfinden welche 2 kunden sich ähnlich sind, von ihren ganzen Einkäufen. Also wer was gekauft hat und gebe die 2 Kunden aus die am ähnlichsten zu Kunde 1 sind.
Als Ausgangsbasis habe ich einfach den Kunden mit der Kundennummer 1 (Peter) gewählt.
Die Kundennummer ist der index wert im array also kundennummer für Andy ist 0 usw.

Zur Info ich habe auch eine Methode, wo ich später die Kundenummer eingeben und so einen anderen Kunden als Peter wählen kann.🙂

Ich habe jetzt erstmal eine Scheilfe erstellt, die jeweils alle Kunden mit ihren Produkten ausgeben kann.
Aber wie finde ich die 2 Kunden, die die gleiche Anzahl oder die Anzahl der meisten übereinstimmungen gekauft haben, wie Peter(1)??

Java:
import java.io.Console;

public class kundenvergleich {
  
private static String[] kunden = {"Andy","Peter","Claus","Dante","Elsa","Franz","Gudrun","Hans","Ina","Jonas","Kurt","Laura","Matthias","Norbert","Olaf","Patrick","Roman","Susi","Tobi","Ulf","Vernocia","Werner"};
  private static String[] produkte = {"Apfel","Melone","Kirschen","Birnen", "Ananas", "Gurken", "Tomaten","Kiwi","Apfrokados", "Zitronen", "Kokusnus","Maracuja","Datteln","Granatapfel","Wilde Pflaume","Jochelbeere"};
  private static boolean[][] gekauft = {
    {true,true,true,false,false,false,false,false,false,false,false,false,false,false,false,false},
    {false,true,true,false,false,false,false,false,false,false,false,true,false,false,false,false},
    {true,false,true,true,false,false,false,false,false,false,false,false,false,false,false,false},
    {false,false,false,false,true,true,true,true,false,false,false,false,false,false,false,false},
    {false,false,false,true,false,false,true,true,true,false,false,false,false,false,false,false},
    {false,false,true,false,false,false,false,false,true,false,true,false,false,false,true,false},
    {false,false,true,false,false,false,false,true,true,false,false,false,false,false,false,false},
    {false,false,false,false,false,false,false,false,false,false,false,false,false,true,true,true},
    {false,false,false,false,false,false,false,false,true,false,true,true,false,false,true,true},
    {false,false,false,false,false,false,true,true,true,false,false,false,false,false,false,false},
    {false,false,false,false,false,false,false,false,false,true,false,true,false,false,false,true},
    {false,false,false,false,false,false,false,true,false,true,true,false,true,false,true,false},
    {true,true,false,true,false,false,false,false,false,false,false,true,false,false,false,false},
    {false,false,false,false,true,true,false,true,false,false,false,false,false,false,false,false},
    {false,false,false,false,false,true,false,false,false,false,true,false,true,false,false,false},
    {false,false,true,false,false,false,false,true,true,false,true,false,false,false,false,false},
    {false,false,false,false,false,false,false,false,false,false,false,true,false,true,true,true},
    {false,false,false,false,false,false,false,false,false,true,true,false,true,false,false,false},
    {false,false,false,false,false,false,false,false,false,false,false,true,false,true,false,true},
    {false,false,false,false,false,false,false,false,false,true,false,false,false,false,true,false},
    {false,false,false,false,true,true,false,false,false,false,false,false,false,false,false,false},
    {false,true,true,false,false,false,false,false,false,false,false,true,false,true,false,false}};
  
  public static void main(String[] args) {
    int kundennr = 1;
    vergleichzwischenkunden(kundennr); 
  }
  
  //aufgabe 10 
  private static void vergleichzwischenkunden(int kundennr) { 
    
    for (int i = 0; i < kunden.length; i++) {
      
      System.out.println("Kunde: " + kunden[i]+ " hat folgendes gekauft:");
      
      for (int j = 0; j < produkte.length; j++) {
        
        if(gekauft[i][j] == true){
          System.out.println(produkte[j]); 
        }
      }
      System.out.println(" ");
    } 
  } 
}
 
Zuletzt bearbeitet:
Du musst nur für jeden Kunden einmal die Liste aller anderen Kunden durchgehen und für jeden Schauen, welche Produkte er hat und die Anzahl der Überschneidungen merken. Dann führst du nebenbei eine Liste (oder besser: PriorityQueue) und fügst den neuen Kunden zusammen mit seinen Überschneidungen ein (Anmerkung: Du kannst auch einfach nur 2 Elemente in der Queue halten, indem du guckst, ob das momentane Element mehr Überschneidungen hat, als das schlechtere der beiden Elemente in der Queue).

Die Frage ist, willst du es schön Objektorientiert machen oder hässlich ,,funktional'' ?
 
Ok danke für deine Hilfe, aber ich glaube soviel Ahnung habe ich noch nicht das ich das richtig umsetze kann. Ich weiß das Objektorientiert besser ist vom Aufbau her, aber wir lernen im Moment eher die Grundlagen also muss ich es noch "funktional'' machen. 🙂
also muss ich auf meine schleife zurückgreifen und dann irgendwie die kunden unterscheiden welche produkte sich vom ausgangskunde unterscheiden? von PriorityQueue habe ich noch nicht gehört.
Ich komme bei dir Aufgabe nicht weiter vielleicht liegt auch an der Sonne 😉😀
 
Zuletzt bearbeitet:
SCNR,
Sind die Adjektive Objektorientiert=schön bzw.funktional''=hässlich wirklich wahr?:lol:
Ausserdem glaube ich, das mein Kollege njans hier wohl imperativ meinte😀

Aber du kannst zählen wie viele Übereinstimmungen zwischen zwei Kunden bestehen. Du weisst ja schon, dass Kunde x ein Produkt gekauft hat.
Java:
  if(gekauft[i][j] == true)
das musst du doch "nur" noch abstimmen, ob Kunde 1 (Peter) es ebenfalls gekauft hat und die Zahl der übereinstimmenden Produkte um eins erhöhen. Also bekommst du für alle Kunden heraus, wie gross die Anzahl der gleichgekauften Produkte gegenüber Kunde-1 (Peter) ist.
Beispiel
Kunde-0 Übereintimmungen:0
Kunde-3 Übereinstimmungen: 4
Kunde-5 Übersinstimmungen:2
...
Also sortierst du noch die Liste noch nach Übereinstimmungen
 
Ok ich habe es jetzt hinbekommen das nur noch die Produkte ausgegeben werden, die auch kunde 1 gekauft hat indem ich ein weitere Bedingungin if hingefügt habe. Wie kann ich denn jetzt sortieren mit BubbleSort oder QuickSort oder was anderes? Sodass ich jetzt die kunden sortieren kann

[JAVA=42]

for (int j = 0; j < produkte.length; j++) {

if(gekauft[j] == true && gekauft[kundennr][j]){
System.out.println(produkte[j]);
}
}

[/code]

Ausgabe der Schleife sieht so aus(nure die ersten 4 Ergenisse kopiert)
Kunde: Andy hat folgendes gekauft:
Melone
Kirschen

Kunde: Peter hat folgendes gekauft:
Melone
Kirschen
Maracuja

Kunde: Claus hat folgendes gekauft:
Kirschen

Kunde: Dante hat folgendes gekauft:
 
Zuletzt bearbeitet:
Wie kann ich denn jetzt sortieren mit BubbleSort oder QuickSort oder was anderes? Sodass ich jetzt die kunden sortieren kann
Weder noch😉
Ich meinte ja, das du die Anzahl Übereinstimmungen ZÄHLEN solltest.

Und zwar baust du dir eine Zählkasse, die einerseits einen Kunden speichert UND seine Anzahl an Übereinstimmungen.
VOR deiner kunden-Schleife initialisiert du alles richtig
Java:
		List<Zaehler> uebereinstimmungen = new ArrayList<>();
		for (String kunde : kunden) {
			uebereinstimmungen.add(new Zaehler(kunde, 0));
		}
In dieser Schleife instanzierst du ein Zählerobjekt für den Kunden mit einem initialen Übereinstimmungszähler von 0;
Java:
for (int j = 0; j < produkte.length; j++) {
        
        if(gekauft[i][j] == true && gekauft[kundennr][j]){
          System.out.println(produkte[j]);
        }
Hier erhöhst du den Zählerstand um eins statt auszugeben.

Sortieren kannst du deine Zählklasse, die wie folgt definiert sein sollte:
Java:
class Zaehler implements Comparable<Zaehler> {

	public Zaehler(String kunde, int i) {
		// TODO Auto-generated constructor stub
	}

	@Override
	public int compareTo(Zaehler o) {
		// TODO Auto-generated method stub
		return 0;
	}
Dann reicht ein Aufruf, um zu sortieren
Java:
Collections.sort(uebereinstimmungen);
Deine compare-Methode in Zähler muss -1, 0, +1 zurückgeben, wenn Objekt <, = oder groesser ist. Hier reicht aus, einfach AnzahlÜbereinstimmugen-o.getAnzahlUebereinstimmungen() zu machen.
 
Ok ich habe jetzt noch einen Zähler mit eingebaut, der mir jeweils die Anzahl der übereinstimmen Produkte ausgibt. Sorry, aber das mit der Arrayliste verstehe ich alles nicht. Sowas hatten wir noch nicht. 😳:bahnhof:

[JAVA=42]
for (int i = 0; i < kunden.length; i++) {
int zaehler = 0;
System.out.print(kunden+ ": ");

for (int j = 0; j < produkte.length; j++) {

if(gekauft[j] && gekauft[kundennr][j]){

//System.out.println(produkte[j]);
zaehler++;
}

}
System.out.println(zaehler);
}

[/code]

Ausgabe
Andy: 2
Peter: 3
Claus: 1
Dante: 0
Elsa: 0
Franz: 1
Gudrun: 1
 
Sieht doch ganz gut aus, oder?

Jetzt musst du dir nur noch merken, wer die meisten Übereinstimmungen hat.
Nach
Java:
         zaehler++;
        }
}
// Einfuegen
if (zaehler > besterWert) {
bestWert = zaehler;
besterKunde = kunden[i];
}




In deinem Beispiel Peter, in der Annahme, das es NICHT der Kunde ist, den du "prüfen" möchtest, denn sonst ist es Andy. Weil Peter zu sich selbst, NATÜRLICH die meisten Übereinstimmungen hat.😉
 
Zuletzt bearbeitet:
ok ich habe den code eingesetzt und die Variablen deklariert.
also wenn ich die Werte per Hand festlege klappt es schon mal :toll:
aber wo wähle ich die besterWert und bestWert aus.

int besterWert = ?;
int bestWert = ?;
String besterKunde = "";

[JAVA=42]
zaehler++;
}
}
System.out.println(zaehler);

if (zaehler > besterWert) {
bestWert = zaehler;
besterKunde = kunden;
}
System.out.println("");

}
System.out.println("Bester Kunde mit Übereinstimmung ist: " + besterKunde);

}
}

[/code]
 
Zuletzt bearbeitet:
Wenn ich deinen Code richtig verstehe, rufst du vergleichzwischenkunden() auf, um den besten Kunden mit den meisten Übereinstimmungen zu ermitteln, oder?

Dann scheint mir die richtige Ort, die Werte zu initialisieren, BEVOR du in der Schleife über alle Kunden iterierst.
Java:
int besterWert = -1;
String besterKunde = "";
Dann ist besterWert mit -1 und der Name des besten Kunden mit "" gut belegt, weil jeder Kunde mindestens 0 Übereinstimungen hat und du somit mindestens einen Kunden finden wirst.

Übrigens dabei der Hinweis, wie du gedenkst, wenn mehrere Kunden gleichviele Übereinstimmungen haben?

PS:
Da ich auch auf clean-code achte, fällt mir sofort auf, das der Name vergleichzwischenkunden doof ist, da er nichts vergleicht, um dann was zu tun?

Ich fände getBestAgreedCustomer besser und dann sollte die Methode auch den Kunden zurückliefern und folglich so definiert sein.
String getBestAgreedCustomer(int kundennr);

PS2:
An dieser Funktion merkst du auch, das du anscheinend manchmal die KundenNummer und manchmal den KundenNamen verwendest. Leider wird nicht klar, warum ich die Funktion mit einer Nummer, welche?, aufrufen muss.

PS3:
Dieses sind Dinge, die dir beim Vorgehen TDD (Test-driven-development) SOFORT aufgefallen wären, weswegen du überdenken solltest, ob deine Vorgehensweise (loslegen mit Implementierung) so richtig ist.
 
Ok Ich habe eine Methode erstellt, wo ich die Kundennummer eingeben kann und sie dann in die getBestAgreedCustomer(int kundennr) übergeben wird.

Das mit dem return Wert habe ich schon erledigt gehabt, sodass dann der Namen zurückgegegeben wird als String.🙂
Das mit bester Kunde hatte auch auch ausserhalb der Scheifle eingebaut, aber warum -1 bei besterWert
und in der if Anweisung müsste das nicht in Zeile 2 besterWert sein?
wei lwas ich nocht nicht ganz so verstehe ist bestWert und besterWert?
[JAVA=42]
if (zaehler > besterWert) {
bestWert = zaehler;
besterKunde = kunden;
}
[/code]
 
aber warum -1 bei besterWert

Das ist der startwert. In deinem Programm wirst du logischerweise minimal 0 Elemente zwischen zwei beliebigen Kunden haben können. Wenn du am Ende allerdings -1 zurück bekommst, dann weißt du, dass da etwas a) schief gelaufen ist oder b) keine Kunden verglichen wurden.
 
Ich habe noch ein bisschen herumprobiert, aber der Rückgabewert stimmt nicht. Der Wert ist immer meine kundenr, die ich eingegeben habe. Also bei Eingabe von 0 = Peter, 1 = Andy ....???:L

Java:
private static String getBestAgreedCustomer(int kundennr) { 
    int besterWert = -1;
    String besterKunde = "";
    
    for (int i = 0; i < kunden.length; i++) {
      int zaehler = 0;
      
      for (int j = 0; j < produkte.length; j++) {
        
        if(gekauft[i][j] && gekauft[kundennr][j]){
          zaehler++;
        } 
      }
      System.out.println(kunden[i]+ ": " + zaehler);
      
      if (zaehler > besterWert) {
        besterWert = zaehler;
        besterKunde = kunden[i]; 
      } 
    }
    
    return besterKunde;
  }
 
Dein Problem ist, dass du auch den Kunden mit sich selbst vergleichst 😉
Und der passt natürlich 100%ig. Daher solltest du wohl sicherstellen, dass i niemals die kundennummer ist.
 
Ich habe jetzt eine weitere Bedingung in der if Anweisung eingefügt.
Jetzt scheint es zu gehen.

[JAVA=42]
if (zaehler > besterWert && kunden != kunden[kundennr])
[/code]
 
Hatten njans und ich bereits gesagt und bin versucht rtfm zu sagen:rtfm:

njans: Dein Problem ist, dass du auch den Kunden mit sich selbst vergleichst
turtle: In deinem Beispiel Peter, in der Annahme, das es NICHT der Kunde ist, den du "prüfen" möchtest
 

Zurück
Oben