Kurzes Java-Programm, das sich komisch verhält

X

Xulu200

Mitglied
Hallo!

Zuerst: Ich nutze IntelliJ IDEA 2020.1.1 Ultimate Edition.

Eigentlich wollte ich nur fix etwas schreiben, um damit ein Problem zu lösen. Bei dem Problem geht es um die Anzahl von Ziffernkombinationen unter bestimmten Eigenschaften. Die Details sind an der Stelle nicht relevant.

Bevor ich die Eigenschaften abfragen kann, benötige ich die n! Zahlenkombinationen, wenn ich alle n-stelligen Zahlen (jede Ziffer darf nur einmal vorkommen) als Listen innerhalb einer Menge haben möchte. Es muss nicht schön oder performant sein, sondern nur die Menge der Listen liefern.

Deshalb schrieb ich Folgendes:
Java:
import java.util.*;

public class main {
    public final static int c = 2;
    static HashSet<ArrayList<Integer>> set = new HashSet<ArrayList<Integer>>();

    public static void main(String args[]) {
        m(new ArrayList<>(), makeSet(c), c);
        System.out.println("SIZE:");
        System.out.println(set.size());
    }

    public static HashSet<Integer> makeSet(int maximum) {
        HashSet<Integer> s = new HashSet<Integer>();
        for (int i = 1; i <= maximum; i++) {
            s.add(i);
        }

        return s;
    }

    public static void m (ArrayList<Integer> list, HashSet<Integer> s, int len) {
        if (len == 0) {
            System.out.println("===\nlist bei len == 0: " + list);

            set.add(list);
            System.out.println("set: " + set + "\n===");
        }
        else {
            int counter = 1;

            for (int u : s) {
                ArrayList<Integer> l = list;
                System.out.println("l Anfang for: " + l);
                l.add(u);
                HashSet<Integer> q = new HashSet<Integer>();
                for (int z : s) {
                    if (z != u) {
                        q.add(z);
                    }
                }
                System.out.println("======\nLoop-Nr: " + counter);
                System.out.println("l = " + l);
                System.out.println("q = " + q);
                System.out.println("======\n");
                counter++;
                m(l, q, len-1);
            }
        }
    }

Da sind jetzt ein paar println-Ausgaben drin, weil ich dachte, das Problem könne ja nicht so lang sein und so fügte ich nach und nach mehr ein.

Nun, natürlich soll es am Ende um weit höhere Zahlen gehen, aber zum Erkennen des Problems sollte der Fall c = 2 reichen.
Ich erwarte also die Ausgabe, dass set am Ende [[1,2],[2,1]] enthält.

Die Ausgabe, bestehend aus den printlns, sieht aber so aus:

Code:
l Anfang for: []
======
Loop-Nr: 1
l = [1]
q = [2]
======

l Anfang for: [1]
======
Loop-Nr: 1
l = [1, 2]
q = []
======

===
list bei len == 0: [1, 2]
set: [[1, 2]]
===
l Anfang for: [1, 2]
======
Loop-Nr: 2
l = [1, 2, 2]
q = [1]
======

l Anfang for: [1, 2, 2]
======
Loop-Nr: 1
l = [1, 2, 2, 1]
q = []
======

===
list bei len == 0: [1, 2, 2, 1]
set: [[1, 2, 2, 1], [1, 2, 2, 1]]
===
SIZE:
2

Wie kann das sein, was sehe ich nicht? Danke sehr für die Hilfe! :)

Liebe Grüße
Xulu
 
L

LimDul

Top Contributor
Erster Ratschlag. Bennene deine Variablen sinnvoll.

Java:
            for (int u : s) 
               for (int z : s)
Das sind keine sinnvollen Variablen. Wofür steht u, wofür z? s ist vermutlich das set.

Bei deiner Ausgabe gibt es l und q. Ich hab keine große Lust diese Verwirrung zu lösen und versuchen nachzuvollziehen was du dir dabei gedacht hast. Das einzige was ich auf die Schnelle sehe - du hast die beiden Schleifen und immer wenn es mindestens ein z gibt, was vom u abweicht. wird das z in q hinzugefügt. Wenn du die Liste 1,2 und enthält, dann ist das eigentlich sowohl für für 1 als auch 2 der Fall, weil für beide gibt es in dem Set ein Element das anders ist. Aber mir ist das zu komplex auseinderzudröseln was nun wieder q ist.
 
X

Xulu200

Mitglied
Okay, ich erkläre kurz:

1. Ich habe ein Set aus Listen (ja, es sind Permutationen), welches leer ist.
2. Ich rufe die rekursive Funktion m auf. Ihr übergebe ich eine neue leere Liste, ein Set aus den Zahlen von 1 bis c und das c.
3. m soll nun rekursiv arbeiten:
4. Eine Liste wird an m übergeben, ebenso eine Menge aus möglichen Ziffern, die an die Liste angehängt werden können.
5. Die Abbruchbedingung ist, dass die gewünschte Länge erreicht ist (also dann c).
6. Falls die Länge erreicht wurde, habe ich eine Permutation gefunden und kann diese in mein set aufnehmen.
7. Falls ich die Länge noch nicht erreicht habe, möchte ich mehrere rekursive Aufrufe starten. Für jedes mögliche Zeichen, das ich an die Liste anhängen kann, einen. Dabei machen s und z nichts Besonderes. Sie sorgen ausschließlich dafür, dass ein angehängtes Zeichen für den rekursiven Aufruf nicht mehr als anhängbar zur Verfügung steht.
Beispiel:
c = 8 und der Durchlauf steht bei [7,3,5,2]. m wird aufgerufen, indem [7,3,5,2] als bisheriges Ergebnis übergeben wird (Liste) und die Menge, die übergeben wird, ist [1,4,6,8], also die noch zu ergänzenden Zahlen. Die verbleibende Länge ist dann natürlich 4.

Tatsächlich gibt es fertige Lösungen und die Dokumentation ist auch nicht existent. Mit dem Programm möchte ich nach seinem Dienst nicht weiterarbeiten und kein anderer wird das Programm übernehmen. Da es nicht wesentlich länger wird und in seiner Kürze auch nicht sonderlich komplex, hatte ich das jetzt so gelassen.

Ich möchte trotz der Möglichkeit, das Programm neu schreiben zu können, verstehen, warum diese Implementierung nicht funktioniert.

Danke für eure Antworten! :)
Grüße
Xulu
 
X

Xulu200

Mitglied
Gelöst durch:

von
ArrayList<Integer> l = list;
zu
ArrayList<Integer> l = (ArrayList<Integer>) list.clone();

und von
m(l, q, len-1);
zu
m((ArrayList<Integer>) l.clone(), q, len-1);
 
kneitzel

kneitzel

Top Contributor
In so einem kleinen Programm noch irrelevant aber in Projekten bezüglich Refactoring Möglichkeiten und so nicht sehr schön:
Statt einem clone Aufruf (der geht nur auf konkreten Klassen, die es implementieren, nicht auf Interfaces und man sollt ein der Regel gegen Interfaces implementieren!) solltest Du einfach eine neue ArrayList erzeugen. Ein Konstruktor nimmt auch eine Collection mit Elementen.

Also wäre der Code dann: ArrayList<Integer> l = new ArrayList<Integer>(list);

Das funktioniert auch, wenn list statt ArrayList nur List (also genaue Implementation nicht bekannt) oder LinkedList oder sonst irgendwas ist.

Die Problematik mit dem Refactoring von oben noch erläutert:
a) Du machst list aus irgend einem Grund zu einer LinkedList. Die Deklaration von list kann ja entfernt von der Deklaration von l sein. Du kannst es also übersehen. Und du bekommst es erst zur Laufzeit mit, weil der cast fehl schlägt.
b) Clean Code (z.B. Robert C Martin alias Uncle Bob in seinen Büchern) empfiehlt, generell gegen Interfaces zu programmieren wo möglich. Klar, bei der Erstellung einer Instanz geht das nicht - da muss irgendwo z.B. das new ArrayList<Integer>() kommen, aber bei allem, was Du weiter gibst oder so, sollte es dann das Interface sein. Und Du nutzt dann nur das Interface.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
P kurzes Codeausführen Java Basics - Anfänger-Themen 3
J kurzes problem zu JPanel Hinergrundfarbe Java Basics - Anfänger-Themen 20
C Bitte kurzes Feedback - JavaVersionen Java Basics - Anfänger-Themen 6
V ganz kurzes kskb mit Problem - keine Ausgabe Java Basics - Anfänger-Themen 2
R kurzes if-then-else statement Java Basics - Anfänger-Themen 8
Zrebna Frage zum "Referenzen-konzept" in Java Java Basics - Anfänger-Themen 8
C java.util Timer läuft zu langsam? Java Basics - Anfänger-Themen 1
T Klassendiagramm in Java überführen Java Basics - Anfänger-Themen 2
Gaudimagspam Caesars Code entziffern in Java Java Basics - Anfänger-Themen 8
V Gehalt berechnen in Java Java Basics - Anfänger-Themen 6
java3690 Java- liste füllen ud die werte addieren Java Basics - Anfänger-Themen 13
justemii Gehalt berechnen - Aufgabe Java-Programm Java Basics - Anfänger-Themen 9
P Mit iPad Java lernen Java Basics - Anfänger-Themen 15
W Java in Exe Datei umgewandelt, Ressourcen fehlen (Bilder und Audiodateien) Java Basics - Anfänger-Themen 1
N Best Practice How can I creat a programm with java under windows 10 in order to open an spreadsheet in libreoffice calc format Java Basics - Anfänger-Themen 11
T Start-Activity für Java Maven Web-Anwendung festlegen Java Basics - Anfänger-Themen 2
J Java FX - Label aktualisieren Java Basics - Anfänger-Themen 1
A Hilfe bei Java Projekt Java Basics - Anfänger-Themen 4
G Java Bruchrechner Addition, Multiplikation... Java Basics - Anfänger-Themen 12
M Java Einstellung von Apache POI für MS Word Erstellung mit Eclipse Java Basics - Anfänger-Themen 6
B Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException Java Basics - Anfänger-Themen 8
T Java Swing - Dreieck zeichnen mit verschiedenen Variablen Java Basics - Anfänger-Themen 8
P Wie für EIN Java Programm von 64bit Java (=Standard) auf 32bit Java Installation (Windows) umschalten? Java Basics - Anfänger-Themen 6
C Suche Nachhilfe in Java Java Basics - Anfänger-Themen 5
B java.io.OutputStream zu java.io.InputStream konvertieren Java Basics - Anfänger-Themen 18
A Scanner Befehl Java Anfänger Java Basics - Anfänger-Themen 8
M Java entity und wertklassen Java Basics - Anfänger-Themen 2
G Java Vererbung Java Basics - Anfänger-Themen 8
M Java Klasse Object Java Basics - Anfänger-Themen 5
M Java GUI label ändert sich erst zum Schluss Java Basics - Anfänger-Themen 4
G Java Lambda Ausdrücke Java Basics - Anfänger-Themen 19
M Java GUI explorer aufrufen um Pfad zu bekommen Java Basics - Anfänger-Themen 3
M Java Anweisungen Java Basics - Anfänger-Themen 4
M Java 8 Lambda Expression Java Basics - Anfänger-Themen 1
S Java Array Probleme Java Basics - Anfänger-Themen 3
Mr_Kleeblatt Operatoren if (arri[i] != "test.java"&& arri[i] != "test.class") Java Basics - Anfänger-Themen 3
S Java Stream API Java Basics - Anfänger-Themen 6
S Java Array Problem... Java Basics - Anfänger-Themen 2
M Java Listen Java Basics - Anfänger-Themen 4
G Java Object value und entity? Java Basics - Anfänger-Themen 2
_Zabuza_ Erste Schritte Wie am effektivsten Java lernen als Anfänger? Java Basics - Anfänger-Themen 12
G Java Dateisystem Java Basics - Anfänger-Themen 4
G Java charAt Methode Java Basics - Anfänger-Themen 10
L Java lernen Java Basics - Anfänger-Themen 1
G Rot-Schwarz-Bäume Java Java Basics - Anfänger-Themen 10
G Java LinkedList remove Methode Java Basics - Anfänger-Themen 5
G Java LinkedList Java Basics - Anfänger-Themen 6
G Java eingelesene Zahlen Java Basics - Anfänger-Themen 2
Y Java andere Klasse aufrufen Java Basics - Anfänger-Themen 6
I Java zweidimensionales array befüllen mit for-schleife Java Basics - Anfänger-Themen 2
Z vereinfachtes Wörterbuch in java modellieren Java Basics - Anfänger-Themen 10
L Zufälliges Objekt aus der ArraylList ohne java.util.Random Java Basics - Anfänger-Themen 56
S Geht das bei Java ? Java Basics - Anfänger-Themen 11
T Java Anfänger mit konkreten Fragen Java Basics - Anfänger-Themen 2
C Java Spiel Java Basics - Anfänger-Themen 3
R Java SQL Fehler! Java Basics - Anfänger-Themen 4
CT9288 Fragen zu Java Java Basics - Anfänger-Themen 16
M Java Version Verständnisfrage Java Basics - Anfänger-Themen 16
G Java equals() Methode Java Basics - Anfänger-Themen 9
G Java Objekte auf Duplikate testen Java Basics - Anfänger-Themen 4
D Java Einstieg Java Basics - Anfänger-Themen 4
K Java Projekt Hilfe Java Basics - Anfänger-Themen 5
B Java Mail -> Mail senden, ist aber nich in IMAP unter "Gesendet" Java Basics - Anfänger-Themen 3
jmar83 Bluetooth-Zugriff, braucht es dazu plattformabhängige Libraries oder kann das Java mittlerweile selbst? Java Basics - Anfänger-Themen 10
E Macht Java Rechenfehler beim Potenzieren und Mod? Java Basics - Anfänger-Themen 5
F Java GUI-PaintComponent funktioniert nicht Java Basics - Anfänger-Themen 1
Z Methode zum Heraufinden von Anagrammen ohne Java API, Ausnahme String Java Basics - Anfänger-Themen 14
K Java Aufgaben-Wie ran gehen? Java Basics - Anfänger-Themen 6
S Kreisberechnung3 Buch: Programmieren lernen mit Java von Hans-Peter Habelitz Java Basics - Anfänger-Themen 39
V Ersätze für Java-Scanner Java Basics - Anfänger-Themen 9
M Quiz in Java programmieren mit Array Java Basics - Anfänger-Themen 8
D java.lang.NullPointerException Java Basics - Anfänger-Themen 19
J Welche Java-Version installieren Java Basics - Anfänger-Themen 9
A Java.util.Arrays Java Basics - Anfänger-Themen 15
X Reverse algorithm engineering (Java code) Java Basics - Anfänger-Themen 6
C Wie habt Ihr angefangen mit der Java Programmierung, ohne Programmiervorkenntnisse Java Basics - Anfänger-Themen 8
G JAVA Einstieg Java Basics - Anfänger-Themen 26
V_Fynn03 Beliebiges Element in einer Liste löschen (Java)(Lineare Datenstrukturen) Java Basics - Anfänger-Themen 9
F java.util.ArrayList Java Basics - Anfänger-Themen 3
I Java Klassen "Graphics" und "MouseEvent" kombinieren Java Basics - Anfänger-Themen 7
C Methoden Java ist auch eine Insel Listing 2.40 Recursion Java Basics - Anfänger-Themen 7
A Java . punkt neben einer Zahl. Java Basics - Anfänger-Themen 1
G Java-Programm Terminal Java Basics - Anfänger-Themen 2
K Failed to create the Java Virtual Machine Java Basics - Anfänger-Themen 1
T Java Intent Java Basics - Anfänger-Themen 12
G Java Binärer Suchbaum Java Basics - Anfänger-Themen 1
N Java CSV Datei auslesen Java Basics - Anfänger-Themen 6
K Java Anfänger Java Basics - Anfänger-Themen 5
Dimax In Java File (nicht in Java Projekt) mysql Driver importieren Java Basics - Anfänger-Themen 3
M Java Rekursion Java Basics - Anfänger-Themen 9
K Java programmieren Java Basics - Anfänger-Themen 6
G Java Abstrakte Methoden Java Basics - Anfänger-Themen 2
J Java TextArea Text bei hinzufügen makieren Java Basics - Anfänger-Themen 1
D Java Scanner Java Basics - Anfänger-Themen 9
G Java LinkedList Java Basics - Anfänger-Themen 3
G Java Listen und Iterator Java Basics - Anfänger-Themen 2
M Java Objektbeziehungen Java Basics - Anfänger-Themen 4
M Lösung Aufgabe - Java Programmiren lernen für Dummies Java Basics - Anfänger-Themen 11
Dimax Java Programm mit exec starten Java Basics - Anfänger-Themen 5
M Java Code Verständnis Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Anzeige

Neue Themen


Oben