Input/Output Wörter aus einer .txt Filtern, welche nicht mit den Definierten Buchstaben gebildet werden können

niklas_meyer

Mitglied
Guten Abend Leute,

ich stehe leider ein wenig auf dem Schlauch...
Das Programm arbeitet größten Teils so wie es soll, es liest eine Datei ein, in der pro Zeile ein Wort steht. Dann kontrolliert das Programm ob Das wort Buchstaben enthält, die im Programm definiert sind (Buchstabenhäufigkeit). Ist das Wort länger als 4 Zeichen wird das Wort ignoriert. Besteht das Wort nur aus den Definierten Buchstaben wird es richtig in einer Punktmatrix Anzeige wiedergegeben. Ist aber eine Buchstabe dabei, der nicht definiert ist wird er einfach weggelassen z.B. es wurde definiert "N" und "M" dann kommt das Wort "Moin" und in der Anzeige kommt "M N". Und wie ich diese Wörter rausfiltern, wo noch andere Buchstaben drin vorkommen, weiß ich nicht. Da stecke ich gerade fest.

Ich arbeite mit Eclipse auf einem Mac
Hier mal mein Code:
Java:
import java.io.IOException;

public class Versuch2 {
            
    public static void main(String[] args) {
        try {
            FileInput leser = new FileInput ("/Users/niklaskoop/Desktop/Wortliste.txt");                // Hier wird mit der Klasse FileInput die zu lesene Datei ins Programm eingefügt und auf                                                                                                         // potentielle fehler überprüft
            String zeile = null;
            try {
                while ((zeile = leser.leseZeile()) != null)                                            // Mit diesem Code wird die Schleife initialisiert, welche die Datei Zeile für Zeile liest,                                                                                                         // solange wie die Zeile den Wert != 0 zurückliefert
                {
                    String ZeileGroß = zeile.toUpperCase();
                    
                    if (ZeileGroß.contains("E") || ZeileGroß.contains("N") || ZeileGroß.contains("I") || ZeileGroß.contains("S") || ZeileGroß.contains("R") || ZeileGroß.contains("A") || ZeileGroß.contains("T")) {
                            
                            char[] Buchstaben = ZeileGroß.toCharArray();
                        
                            char[] Definition = new char[]{'E','N','I','S','R','A','T'};
                                
                                    if (Buchstaben.length < 5) {
                                        PunktmatrixAnzeige5x7 matrixAnzeige = new PunktmatrixAnzeige5x7 ();
    
                                        for(int k = 0; k < Buchstaben.length; k++) {   
                                            
                                            if (Buchstaben[k] == Definition[0]) {
                                            int MatrixE[][] = { { 255, 255, 255, 255, 255 }, { 255, 0, 0, 0, 0 }, { 255, 0, 0, 0, 0 },
                                                    { 255, 255, 255, 255, 0 }, { 255, 0, 0, 0, 0 }, { 255, 0, 0, 0, 0 }, { 255, 255, 255, 255, 255 } };
                                        
                                            matrixAnzeige.addBlock(MatrixE);
                                            
                                        } else if (Buchstaben[k] == Definition[1]) {
                                            int MatrixN[][] = { { 255, 0, 0, 0, 255 }, { 255, 0, 0, 0, 255 }, { 255, 255, 0, 0, 255 },
                                                    { 255, 0, 255, 0, 255 }, { 255, 0, 0, 255, 255 }, { 255, 0, 0, 0, 255 }, { 255, 0, 0, 0, 255 } };
                                        
                                            matrixAnzeige.addBlock(MatrixN);
                                            
                                        } else if (Buchstaben[k] == Definition[2]) {
                                            int MatrixI[][] = { { 0, 255, 255, 255, 0 }, { 0, 0, 255, 0, 0 }, { 0, 0, 255, 0, 0 }, { 0, 0, 255, 0, 0 },
                                                    { 0, 0, 255, 0, 0 }, { 0, 0, 255, 0, 0 }, { 0, 255, 255, 255, 0 } };
                                        
                                            matrixAnzeige.addBlock(MatrixI);
                                            
                                        } else if (Buchstaben[k] == Definition[3]) {
                                            int MatrixS[][] = { { 0, 255, 255, 255, 0 }, { 255, 0, 0, 0, 255 }, { 255, 0, 0, 0, 0 },
                                                    { 0, 255, 255, 255, 0 }, { 0, 0, 0, 0, 255 }, { 255, 0, 0, 0, 255 }, { 0, 255, 255, 255, 0 } };
                                        
                                            matrixAnzeige.addBlock(MatrixS);
                                            
                                        } else if (Buchstaben[k] == Definition[4]) {
                                            int MatrixR[][] = { { 255, 255, 255, 255, 0 }, { 255, 0, 0, 0, 255 }, { 255, 0, 0, 0, 255 },
                                                    { 255, 255, 255, 255, 0 }, { 255, 0, 255, 0, 0 }, { 255, 0, 0, 255, 0 }, { 255, 0, 0, 0, 255 } };
                                        
                                            matrixAnzeige.addBlock(MatrixR);
                                            
                                        } else if (Buchstaben[k] == Definition[5]) {
                                            int MatrixA[][] = { { 0, 0, 255, 0, 0 }, { 0, 255, 0, 255, 0 }, { 255, 0, 0, 0, 255 }, { 255, 0, 0, 0, 255 },
                                                    { 255, 255, 255, 255, 255 }, { 255, 0, 0, 0, 255 }, { 255, 0, 0, 0, 255 } };
                                        
                                            matrixAnzeige.addBlock(MatrixA);
                                            
                                        } else if (Buchstaben[k] == Definition[6]) {
                                            int MatrixT[][] = { { 255, 255, 255, 255, 255 }, { 0, 0, 255, 0, 0 }, { 0, 0, 255, 0, 0 }, { 0, 0, 255, 0, 0 },
                                                    { 0, 0, 255, 0, 0 }, { 0, 0, 255, 0, 0 }, { 0, 0, 255, 0, 0 } };
                                        
                                            matrixAnzeige.addBlock(MatrixT);
                                        }
                                
                            
                                                                    
                                
                            }    Thread.sleep(1000);   
                                matrixAnzeige.loesche();   
                                matrixAnzeige.dispose();
                                    
                        }
                                
                            
                        
                    }
                    
                }
                leser.schliesseDatei();
                IO.println("Programm wurde beendet!");
                System.exit(1);
                
            } catch(InterruptedException e) {
            IO.println("Fehler bei der LED-Anzeige!");
            }
        
        } catch(IOException IOEx) {
        IO.println(IOEx.getLocalizedMessage());
        System.exit(1);
        }
    }
}
 

Jw456

Top Contributor
Du gehst doch in der for Schleife alle definierten Buchstaben durch mit if Else. Mache doch am Ende noch ein Else dort solltest du ankommen wenn es ein anderer Buchstabe ist.
 
K

kneitzel

Gast
Also als erstes möchte ich Dir kurz aufzeigen, wie Du lesbaren Code schreiben kannst. Denn ich bezweifle, dass Du bei Deinem Code noch irgend einen Überblick hast.

Der Trick, den Du von Anfang an machen solltest, ist das "Teile und Herrsche", das Erstellen von Methoden.

Und dazu schreibst Du am Besten immer erst einmal auf, was Du denn genau machen willst:
- Für jede Zeile der Datei:
--> Ist das Wort gültig?
----> ja: Für jeden Buchstaben: addiere eine Matrix.

Das macht dann den Code in der While Schleife sehr klein:

Java:
while ((zeile = leser.leseZeile()) != null) {
    if (istGueltig(zeile)) {
        zeigeStringAufPunktmatrixAnzeige(matrixAnzeige, zeile);
    }
}

Was dieser Block macht ist super zu verstehen und auch einfach zu verstehen.

Und wenn Du in Methoden bist, dann kannst Du Prüfungen auch immer relativ einfach aufbauen:
- Du nimmst Dir true oder false als Default. Dann prüfst Du immer das Gegenteil. Ist das der Fall, dann gibst Du das zurück.

Also es sieht dann so aus:
- Wenn bedingung1 dann return false;
- in irgend einer Schleife
--> wenn bedingung2 dann return false;
- return true;

Das kannst Du bei istGueltig verwenden:
- ist die Länge > 4 -> false
- für jeden Buchstaben: ist der Buchstabe ungültig? -> false
- -> true


Und dann noch ein Trick: Konstanten:
Nutz im Code wenn möglich keine bis wenig Literale. Definiere die am Besten als Konstanten. Dann wird die Bedeutung im Code schneller klar.

Also oben ein static public final int MAX_LAENGE_WORT = 4;

Der nächste Trick: Nutz Datentypen besser. Solltet Ihr Maps kennen, dann wäre das eine Möglichkeit. Falls ihr die noch nicht haben solltet: Pack die Daten in Arrays.

Ansonsten mach z.B. ein char Array mit den gültigen Buchstaben. Dann brauchst Du nur eine Prüfung, ob der Buchstabe des Wortes in dem Array enthalten ist.



Dieses beschriebene Vorgehen führt schnell und einfach zu einer funktionierenden Lösung. Zur Not kannst Du auch einzelne Methoden schnell testen in der main Methode. Wenn Du also eine Methode hast, die prüft ob ein char in einem char Array ist: Dann erstell ein char Array und rufe das auf und gib das Ergebnis aus. Dann siehst Du direkt, ob Dein Code funktioniert mit einfachen Tests. (Das ist übrigens das, was man in der Software Entwicklung dann auch macht. Jede Methode bekommt dann auch eine (oder mehrere) Testmethode, die das prüft. Das aber nur am Rand mal erwähnt.)

Hilft Dir das weiter? Bekommst Du damit deinen Code strukturierter und übersichtlicher (und damit funktionierend) hin?
 

niklas_meyer

Mitglied
Danke erstmal für die ausführliche Antwort, hat schon ein wenig für mehr Verständnis gesorgt.
Aber wie prüfe ich jetzt ob meine Definierten Buchstaben aus dem Char Array in dem in dem char array welches ich mit String.toCharArray aus der Zeile gebildet, hab enthalten sind ? mein Gedanke wäre jetzt eine for-Schleife, welche jede Position aus dem Zeilen-Array mit den Definierten Array vergleicht. Nur die Umsetzung scheitert, weiß nicht wie ich das in die istGueltig Methode einbaue.
 
K

kneitzel

Gast
Danke erstmal für die ausführliche Antwort, hat schon ein wenig für mehr Verständnis gesorgt.
Aber wie prüfe ich jetzt ob meine Definierten Buchstaben aus dem Char Array in dem in dem char array welches ich mit String.toCharArray aus der Zeile gebildet, hab enthalten sind ? mein Gedanke wäre jetzt eine for-Schleife, welche jede Position aus dem Zeilen-Array mit den Definierten Array vergleicht. Nur die Umsetzung scheitert, weiß nicht wie ich das in die istGueltig Methode einbaue.
Die Idee ist doch schon richtig:

Du gehst das Wort Zeichen für Zeichen durch (Dabei ist es erst einmal egal, ob du den String in ein Char Array umwandelst um dies dann durchzugehen, oder ob Du String::charAt nutzt um ein Zeichen heraus zu nehmen.

Hier ist also wichtig, wieder die Komplexität klein zu halten:

- Für jedes Zeichen aus dem Wort:
- - Ist das Zeichen ungültig? --> return false; // Ungültiges Zeichen gefunden -> Wort ist ungültig!
- return true; // Es war kein Zeichen ungültig.

Und "Ist das Zeichen ungültig" kann dann ebenso aufgeschrieben werden - Nur eben dreht man es jetzt um:
- Für jedes Zeichen aus dem Array mit gültigen Zeichen:
- - ist das zu prüfende Zeichen = dem aktuellen Zeichen? --> return true; // Zeichen ist in den gültigen Zeichen gefunden worden.
- return false; // Alle Zeichen wurden geprüft und das Zeichen war nicht dabei.

Also wirklich immer versuchen, nur in einzelnen Schritten zu denken. Also nimm Dir ein leeres Blatt Papier und spiel es durch! Dabei hast Du nichts im Kopf. Du machst nur Sachen mit Dingen, die auf dem Zettel stehen. So hast Du dann evtl. eine bessere Vorstellung, was wann wo verglichen wird.
 

Barista

Top Contributor
Ist aber eine Buchstabe dabei, der nicht definiert ist wird er einfach weggelassen z.B. es wurde definiert "N" und "M" dann kommt das Wort "Moin" und in der Anzeige kommt "M N".
Habe ich richtig verstanden, dass aus "Moin" "M N" werden soll, also beliebig viele zusammenstehende undefinierte Buchstaben durch ein einziges Leerzeichen ersetzt werden sollen?

Wenn ja, dann gibt es folgende Möglichkeiten (nach meiner Meinung, aber das gilt ja immer):

1. Du ersetzt alle undefinierten Buchstaben durch ein Leerzeichen und ersetzt dann alle Leerzeichenpaare durch einzelne Leerzeichen, wiederholend bis es keine Leerzeichenpaare mehr gibt.

2. Du arbeitest mit einem zweiten Index im Ziel-char-Array und am Ende des Durchlaufes erzeugst Du einen String mit der Ergebnis-Länge.

Beim Ersetzen gilt, das in einen neuen String ersetzt wird, String ist unveränderlich.

Alternativ einen StringBuffer oder StringBuilder verwenden, der ist veränderlich.
 

niklas_meyer

Mitglied
Ich bräuchte nochmal Hilfe bei der istGueltig Methode, die Methode sieht bei mir jetzt so aus
Java:
    public static boolean istGueltig (String a) {                                                                                                                                                           
        
        char[] Buchstaben = a.toCharArray();
        char[] Definition = new char[]{'E','N','I','S','R','A','T'};
        
        if (Buchstaben.length > 4) {
            return false;
        } else {
        for (int i = 0;i < Buchstaben.length; i++) {
            for (int j = 0;j < Definition.length;j++) {
                if (Buchstaben[i] == Definition[j]) {
                    return true;
                    }
                }
            } return false;
            
        }
        }

Ich hab jetzt immer noch genau das gleiche Problem wie Anfangs.. bin echt am verzweifeln
 
K

kneitzel

Gast
Du versuchst mehrere Dinge auf einmal zu machen ... Und dabei machst Du einen Fehler:
Das Pattern ist immer:
Am Ende hast Du eine Rückgabe (hier false). Dann dürfen eigentlich alle anderen returns true sein.

Oder um es deutlich zu sagen: Beim ersten gültigen Buchstaben gibst du true zurück ohne weiter zu prüfen.
 

Jw456

Top Contributor
Ein kleiner Tipp du willst scheinbar deine for Schleife Schleife vorzeitig verlassen. Das macht man nicht mit return. Denn da verläßt du die Methode. Was du ja nicht willst.
Du willst ja nur die innere for beenden.

Ich würde auch eine Variable für das true und false benutzen. Und nicht gleich die Methode beenden. Die restlichen Prüfungen willst du ja noch machen.
 

Neumi5694

Top Contributor
Kleine Frage ... darf ein Buchstabe auch öfters verwendet werden? Sprich: Kann "Tee" aus {"E""T"} erstellt werden oder braucht es dafür {"E","E","T"}?

Bitte schreibe "Buchstaben" und "Definition" klein, das sind keine Klassen.
Von der Struktur der Schleife abgesehen hier dein erster Fehler: Du änderst die Groß-/Kleinschreibung der Buchstaben nicht. "e" ist nicht "E".
D.h. du musst beim Vergleich entweder beide Buchstaben in Großbuchstaben konvertieren oder beide in Kleinbuchstaben.

Wozu ist die Abfrage Buchstaben.length > 4 da? Kann ein Wort nicht aus mehr als 4 Buchstaben bestehen?

Du kannst dir das Leben etwas einfacher machen, indem du mit lokalen Variablen arbeitest.
Also anstatt in der Schleife wiederholt ständig auf
Code:
Buchstaben[i]
zuzugreifen, solltest du dir innerhalb der äußeren Schleife eine lokale Variable "buchstabe" definieren, welche den Wert EINMAL ausliest.
Java:
for (int i = 0;i < buchstaben.length; i++) {
    char buchstabe = buchstaben[i];
    //... innere Schleife
}

Noch einfacher wird's, wenn du anstatt der for-to Schleife eine for-each Schleife verwendest, der Index des Buchstaben interessiert dich nämlich in keinster Weise.
Java:
for (char buchstabe : a.toCharArray()) {
    //...
}}
Wenn du dabei auch gleich in Großschreibung konvertieren willst, bietet sich an:
Java:
for (char buchstabe : a.toUpperCase().toCharArray()) {
    //...
}}

Im Inneren dieser der Schleife prüfst du, ob Definition den gesuchten Buchtaben enthält. Falls nicht, dann liefert die Methode false.
Die Logik sollte in Worten so ausschauen

//Für alle Buchstaben 'buchstabe' aus a{
// falls buchstabe nicht in definition vorhanden, Rückgabe false
//}
//return true;

Das meiste davon kannst du sehr einfach umsetzen, bis vielleicht auf die Prüfung, ob der Buchstabe in dem Array der erlaubten Buchstaben vorhanden ist. Versuch, diesen einen Schritt zu isolieren, in eine eigene Methode zu packen. Später kannst du das - falls du willst - ja immer noch zusammenfassen.
 

Neue Themen


Oben