Von Morsecode zu Text

Lights

Mitglied
Hallo,

seit ca. 2 Monaten versuche ich mich im Rahmen einen Workshops auch mal am Thema programmieren, bin also noch blutiger Anfänger was das angeht, umso mehr würde ich mich freuen wenn mir jemand bei meinem Problem helfen könnte.
Wir haben jetzt die folgende Aufgabe bekommen:
Bitte schreibe ein Programm, welches Morsecode (Eingabe durch Punkt, Bindestrich und Leerzeichen) von der Tastatur einliest und nach Beendigung der Eingabe am Bildschirm im Klartext ausgibt.
Als Trenner zwischen den Buchstaben wird ein Leerzeichen angenommen, ein Leerzeichen in der Ausgabe wird durch zwei Leerzeichen in der Eingabe erzeugt.
Als Zeichenvorrat werden die lateinischen Zeichen und das Satzzeichen ‚.‘ verwendet. Fehlerhafte Eingaben sollen ignoriert werden.

Hab jetzt auch die Grundlegende Aufgabe bearbeitet nur weiß ich nicht wie ich aus dem Morse String die einzelnen Buchstaben filtern soll und dann als Text ausgeben lassen kann.

mein Code sieht bisher folgend aus, bedenkt bitte das ich gerade erst angefangen haben dies zur lernen. Mein Code ist also eher sehr schwach

Java:
package großeJavaAufgabe;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Morsecode {

    Map<Character, String> Mcode = new HashMap<Character, String>();

    public void Kodierung() {

        Mcode.put('A', "·-");

        Mcode.put('B', "-···");

        Mcode.put('C', "-·-·");

        Mcode.put('D', "-··");

        Mcode.put('E', "·");

        Mcode.put('F', "··-·");

        Mcode.put('G', "--·");

        Mcode.put('H', "····");

        Mcode.put('I', "··");

        Mcode.put('J', "·---");

        Mcode.put('K', "-·-");

        Mcode.put('L', "·-··");

        Mcode.put('M', "--");

        Mcode.put('N', "-·");

        Mcode.put('O', "---");

        Mcode.put('P', "·--·");

        Mcode.put('Q', "--·-");

        Mcode.put('R', "·-·");

        Mcode.put('S', "···");

        Mcode.put('T', "-");

        Mcode.put('U', "··-");

        Mcode.put('V', "···-");

        Mcode.put('W', "·--");

        Mcode.put('X', "-··-");

        Mcode.put('Y', "-·--");

        Mcode.put('Z', "--··");

        Mcode.put('0', "-----");

        Mcode.put('1', "·----");

        Mcode.put('2', "··---");

        Mcode.put('3', "···--");

        Mcode.put('4', "····-");

        Mcode.put('5', "·····");

        Mcode.put('6', "-····");

        Mcode.put('7', "--···");

        Mcode.put('8', "---··");

        Mcode.put('9', "----·");

        Mcode.put('.', "·-·-·-");

        for (Map.Entry<Character, String> e : Mcode.entrySet()) {
            System.out.println(e.getKey() + " = " + e.getValue()); //Hashmap wird angezeigt
        }
    }

    public String einlesen() {
        Scanner einlese = new Scanner(System.in);
        String in;
        System.out.println("Bitte Morsecode eingeben: \n");

        in = einlese.nextLine();

        Scanner abfrage = new Scanner(System.in);
        String ab;
        System.out.println("Um Ihre Eingabe einzusehen tippen sie 1: ");
        ab = abfrage.nextLine();

        if (ab.equals("1")) {

            System.out.println("Ihre Eingabe: " + in);
        }

        else {

        }

        return in;

    }

    public void umwandeln() {

        String ein = einlesen();

      

    }

    

    public static void main(String[] args) {

        Morsecode mors = new Morsecode();

        mors.Kodierung();
        mors.umwandeln();

    }

}
 

mihe7

Top Contributor
Ok, fangen wir mal ganz allgemein an... In Java schreibt man Bezeichner für Variablen, Methoden und Parameter in lowerCamelCase, für Klasen, Interfaces, etc. dagegen in UpperCamelCase. Sonderzeichen (Umlaute, ß, ...) in Bezeichnern sollte man möglichst vermeiden.

Jetzt zum Code selbst:
1. Deine Map ist verkehrt herum. Du möchtest Morse-Code auf ein Zeichen abbilden, also String -> Character, Du bildest momentan Character auf Strings ab.
2. Die Methode Kodierung kannst Du Dir sparen, wenn Du einen Konstruktor verwendest. Dazu änderst Du einfach public void Kodierung() in public Morsecode() (ja, hier gibt es keinen Rückgabetyp) um. Der Konstruktor wird automatisch bei new Morsecode() aufgerufen.
3. ein Scanner reicht
4. Wenn Du eine Zeile in eingabe eingelesen hast, kannst Du die Zeile an den Leerzeichen mit eingabe.split(" ") in ein String-Array aufteilen. Die Elemente des Arrays entsprechen dann einem einzelnen Morsecode.
5. Frag einfach weiter.
 

Lights

Mitglied
Hey, danke für die schnelle Antwort, ich hab die Map jetzt berichtigt und Kodierung in den Constructor umgewandelt. Das mit .split() habe ich gerade bereits hinzugefügt, habe das ganze jetzt in ne ArrayList gespeichert. Ich füg mal meinen neuen Code rein, jetzt fehlt mir wirklich nur noch das umwandeln der in der ArrayList gespeicherten Morsecodes in Text. Die Bezeichner werde ich im nachhinein natürlich nochmal alle verbessern :)
Wäre toll wenn du mir noch weiterhelfen würdest.
Java:
[Code = java]
package großeJavaAufgabe;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;


public class Morsecode {

    Map<String, Character> Mcode = new HashMap<String, Character>();

    public Morsecode() {

        Mcode.put("·-", 'A');

        Mcode.put("-···", 'B');

        Mcode.put("-·-·", 'C');

        Mcode.put("-··", 'D');

        Mcode.put("·", 'E');

        Mcode.put("··-·", 'F');

        Mcode.put("--·", 'G');

        Mcode.put("····", 'H');

        Mcode.put("··", 'I');

        Mcode.put("·---", 'J');

        Mcode.put("-·-", 'K');

        Mcode.put("·-··", 'L');

        Mcode.put("--", 'M');

        Mcode.put("-·", 'N');

        Mcode.put("---", 'O');

        Mcode.put("·--·", 'P');

        Mcode.put("--·-", 'Q');

        Mcode.put("·-·", 'R');

        Mcode.put("···", 'S');

        Mcode.put("-", 'T');

        Mcode.put("··-", 'U');

        Mcode.put("···-", 'V');

        Mcode.put("·--", 'W');

        Mcode.put("-··-", 'X');

        Mcode.put("-·--", 'Y');

        Mcode.put("--··", 'Z');

        Mcode.put("-----", '0');

        Mcode.put("·----", '1');

        Mcode.put("··---", '2');

        Mcode.put("···--", '3');

        Mcode.put("····-", '4');

        Mcode.put("·····", '5');

        Mcode.put("-····", '6');

        Mcode.put("--···", '7');

        Mcode.put("---··", '8');

        Mcode.put("----·", '9');

        Mcode.put("·-·-·-", '.');

        for (Map.Entry<String, Character> e : Mcode.entrySet()) {
            System.out.println(e.getKey() + " = " + e.getValue());
        }
    }

    public String einlesen() {
        Scanner einlese = new Scanner(System.in);
        String in;
        System.out.println("Bitte Morsecode eingeben: \n");

        in = einlese.nextLine();

        Scanner abfrage = new Scanner(System.in);
        String ab;
        System.out.println("Um Ihre Eingabe einzusehen tippen sie 1: ");
        ab = abfrage.nextLine();

        if (ab.equals("1")) {

            System.out.println("Ihre Eingabe: " + in);
        }

        else {

        }

        return in;

    }

    public void umwandeln() {

       // String ein = einlesen();

        String morsecode = "..."; //Beispiel Morsecode zum testen ohne die Eingabe

        ArrayList<String> Liste = new ArrayList<String>();

        String Woerter[] = morsecode.split(" ");

        for (int i = 0; i < Woerter.length; ++i) {
            String einzelneBuchstaben = Woerter;

            String BuchstabenArray[] = einzelneBuchstaben.split(" ");

            for (int c = 0; c < BuchstabenArray.length; ++c) {

                Liste.add(BuchstabenArray[c]);

            }

        }

    }

    public static void main(String[] args) {

        Morsecode mors = new Morsecode();

        mors.umwandeln();

    }

}
[/code]
 

mihe7

Top Contributor
1. Das BuchstabenArray enthält ja Morse-Codes (Strings)
2. In der Schleife musst Du den zugehörigen Klartext-Character ermitteln, das machst Du über die Map (MCode.get(BuchstabenArray[c]))
3. Statt der Liste nimm einfach einen StringBuilder. Das Ergebnis aus 2. fügst Du dem String einfach mit "append" hinzu.
4. Nach der Schleife gibst Du über StringBuilder#toString() das Ergebnis aus.
 

Lights

Mitglied
Dankeschön, mittlerweile klappt es so wie es klappen soll, eine Frage habe ich noch, da ich ja durch ein Leerzeichen in der Eingabe meine Morsezeichen trenne würde ich gerne durch die Eingabe von 2 Leerzeichen, ein Leerzeichen in der Ausgabe erzeugen, damit ich Wörter trennen kann. An sich müsste das mit Liste.append(" ") funktionierne, allerdings fehlt mir noch das if Statement davor damit er das nur macht wenn in in der Eingabe 2 Leerzeichen vorhanden sind
 

Lights

Mitglied
Das hatte ich bereits auch ausprobiert, klappt auch noch nicht, wobei ich mir gerade nicht sicher bin was du mit deinem zweiten Satz meinst, hab jetzt also nur meine Map ergänzt
 

MoxxiManagarm

Top Contributor
Java:
public String decodeText(String text) {
        StringBuilder sb = new StringBuilder();
     
        for(String s : text.split(" ")) {
            sb.append(mCode.get(s)); // TODO: care about null
        }
     
        return sb.toString();
}

Im Falle eines Split über Doppel-' ' ist ein s in der Iteration ein leerer String. Der wird dann auf ein Leerzeichen in der Ausgabe gemapped, wenn du den Eintrag hast.
 
Zuletzt bearbeitet:

Lights

Mitglied
Ich glaube ich stelle mich gerade sehr dumm an, aber wo soll ich die Methode dann aufrufen?



Java:
package großeJavaAufgabe;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Morsecode {

    /
    Map<String, Character> Mcode = new HashMap<String, Character>();

    public void Kodierung() {

        Mcode.put(".-", 'A');

        Mcode.put("-...", 'B');

        Mcode.put("-.-.", 'C');

        Mcode.put("-..", 'D');

        Mcode.put(".", 'E');

        Mcode.put("..-.", 'F');

        Mcode.put("--.", 'G');

        Mcode.put("....", 'H');

        Mcode.put("..", 'I');

        Mcode.put(".---", 'J');

        Mcode.put("-.-", 'K');

        Mcode.put(".-..", 'L');

        Mcode.put("--", 'M');

        Mcode.put("-.", 'N');

        Mcode.put("---", 'O');

        Mcode.put(".--.", 'P');

        Mcode.put("--.-", 'Q');

        Mcode.put(".-.", 'R');

        Mcode.put("...", 'S');

        Mcode.put("-", 'T');

        Mcode.put("..-", 'U');

        Mcode.put("...-", 'V');

        Mcode.put(".--", 'W');

        Mcode.put("-..-", 'X');

        Mcode.put("-.--", 'Y');

        Mcode.put("--..", 'Z');

        Mcode.put("-----", '0');

        Mcode.put(".----", '1');

        Mcode.put("..---", '2');

        Mcode.put("...--", '3');

        Mcode.put("....-", '4');

        Mcode.put(".....", '5');

        Mcode.put("-....", '6');

        Mcode.put("--...", '7');

        Mcode.put("---..", '8');

        Mcode.put("----.", '9');

        Mcode.put(".-.-.-", '.');

        Mcode.put("", ' ');

    }

    public String einlesen() {
        Scanner einlese = new Scanner(System.in);
        String in;
        System.out.println("Bitte Morsecode eingeben: \n");

        in = einlese.nextLine();

        Scanner abfrage = new Scanner(System.in);
        String ab;
        System.out.println("Um Ihre Eingabe einzusehen tippen sie 1: ");
        ab = abfrage.nextLine();

        if (ab.equals("1")) {

            System.out.println("Ihre Eingabe: " + in);
        }

        else {

        }

        einlese.close();
        abfrage.close();

        return in;

    }

    public void umwandeln() {

        String ein = einlesen();

        StringBuilder Liste = new StringBuilder();

        String Woerter[] = ein.split(" ");

        for (int i = 0; i < Woerter.length; ++i) {
            String einzelneBuchstaben = Woerter[i];

            String BuchstabenArray[] = einzelneBuchstaben.split(" ");

            for (int c = 0; c < BuchstabenArray.length; ++c) {

                Liste.append(Mcode.get(BuchstabenArray[c]));
             
            }

        }
        System.out.println(Liste.toString());
    }

    public void CodeFromFile() throws FileNotFoundException {
        File CodeFile = new File("morseCode.txt");
        Scanner rein = new Scanner(CodeFile);

        while (rein.hasNext()) {
            char Buchstabe = rein.next()
                                 .charAt(0);
            String code = rein.next();
            Mcode.put(code, Buchstabe);

        }
    }

    public void TextFromFile() throws FileNotFoundException, IOException {

        File morseCode = new File("message.txt");
        BufferedReader bufferedReader = new BufferedReader(new FileReader(morseCode));
        String line;

        while ((line = bufferedReader.readLine()) != null) {
            String letter = "";

            for (String morseLetter : line.split(" ")) {

                letter = Mcode.get(morseLetter)
                              .toString();
                System.out.print(letter);
            }

            if (letter.equals(".")) {
                // Zeilenumbruch
                System.out.println();
            } else {
                // Leerzeichen
                System.out.print(' ');
            }
        }

    }

    public String getDecodedText(String text) {
        StringBuilder sb = new StringBuilder();

        for (String s : text.split(" ")) {
            sb.append(Mcode.get(s)); // TODO: care about null
        }

        return sb.toString();
    }

    public static void main(String[] args) {

        Morsecode mors = new Morsecode();

        try {
            mors.CodeFromFile();
            ;
        } catch (FileNotFoundException e) {

            e.printStackTrace();
        }

        try {
            mors.TextFromFile();
        } catch (IOException e) {

            e.printStackTrace();
        }

        mors.umwandeln();

    }

}
 
Zuletzt bearbeitet:

MoxxiManagarm

Top Contributor
Es ist ja so erstmal nur ein Beispiel. Es entspricht aber deiner umwandeln Methode. Du stellst dich nicht dumm an. du hast es dir nur umständlich gemacht und nun bist du verwirrt.
 

mihe7

Top Contributor
nicht sicher bin was du mit deinem zweiten Satz meinst
Wenn wir Anfang und Ende des Strings mal weglassen, dann liefert string.split(" ") die Teile der Zeichenkette, die zwischen je einem Leerzeichen stehen.

Nehmen wir mal Strings s1, s2 und s3 an, die keine Leerzeichen enthalten. Daraus können wir einen String basteln, String s = s1 + " " + s2 + " " + s3.

s.split(" ") liefert nun ein Array, das aus s1, s2 und s3 besteht, also {s1, s2, s3}.

Setzt Du s2 = "" (leerer String), dann ist
Code:
s = s1 + " " + "" + " " + s3
  = s1 + " " + " " + s3
und das von s.split(" ") gelieferte Array {s1, s2, s3} = {s1, "", s3}.

Soweit verstanden?

Der leere String ist jetzt einfach ein besonderer "Morsecode", den Du wie alle anderen Morsecodes auch über deine Map in Klartext (ein Leerzeichen) umwandelst.
 

mihe7

Top Contributor
Kurz: du fügst in Deinen Morsecode-Konstruktor z. B. vor Mcode.put('A', "·-"); noch Mcode.put("", " "); ein. Den Rest kannst Du lassen, wie er ist.
 

MoxxiManagarm

Top Contributor
Hier ein komplexeres Beispiel, damit der Kontext klarer wird:
Java:
public class MorseDecoder {
    private static final Map<String, Character> LOOKUP = new HashMap<>();
    static {
        LOOKUP.put("·-", 'A');
        LOOKUP.put("-···", 'B');
        LOOKUP.put("-·-·", 'C');
        LOOKUP.put("-··", 'D');
        LOOKUP.put("·", 'E');
        LOOKUP.put("··-·", 'F');
        LOOKUP.put("--·", 'G');
        LOOKUP.put("····", 'H');
        LOOKUP.put("··", 'I');
        LOOKUP.put("·---", 'J');
        LOOKUP.put("-·-", 'K');
        LOOKUP.put("·-··", 'L');
        LOOKUP.put("--", 'M');
        LOOKUP.put("-·", 'N');
        LOOKUP.put("---", 'O');
        LOOKUP.put("·--·", 'P');
        LOOKUP.put("--·-", 'Q');
        LOOKUP.put("·-·", 'R');
        LOOKUP.put("···", 'S');
        LOOKUP.put("-", 'T');
        LOOKUP.put("··-", 'U');
        LOOKUP.put("···-", 'V');
        LOOKUP.put("·--", 'W');
        LOOKUP.put("-··-", 'X');
        LOOKUP.put("-·--", 'Y');
        LOOKUP.put("--··", 'Z');
        LOOKUP.put("-----", '0');
        LOOKUP.put("·----", '1');
        LOOKUP.put("··---", '2');
        LOOKUP.put("···--", '3');
        LOOKUP.put("····-", '4');
        LOOKUP.put("·····", '5');
        LOOKUP.put("-····", '6');
        LOOKUP.put("--···", '7');
        LOOKUP.put("---··", '8');
        LOOKUP.put("----·", '9');
        LOOKUP.put("·-·-·-", '.');
        LOOKUP.put("", ' ');
    }
 
    public static String decodeText(String text) {
        StringBuilder sb = new StringBuilder();
    
        for(String s : text.split(" ")) {
            sb.append(LOOKUP.get(s)); // TODO: care about null
        }
    
        return sb.toString();
    }
 
    public static void main(String... args) {
        System.out.println(
                MorseDecoder.decodeText("···· · ·-·· ·-·· ---  ·-- --- ·-· ·-·· -··")
        );
    }
}

Prints:
Code:
HELLO WORLD

Mehr ist es nicht. Du muss nur noch das Fehlerhandling sowie deine Bezeichner etc anpassen und die Eingabe des zu decodierenden Textes hinzufügen.
 

Lights

Mitglied
Danke Leute, ich hatte es die ganze Zeit schon gelöst, ich hatte nur noch eine Methode aufgerufen die die Hashmap aus einer externen Morsecode.txt füllt und in dieser war ("", ' ') natürlich nicht drin, es war also ein einfacher Flüchtigkeitsfehler von mir, trotzdem vielen Dank das ihr mir geholfen habt
 

Lights

Mitglied
Jetzt stellt sich mir doch noch eine ganz andere Frage, wie ist es möglich das ich den Leerstring und den Leerchar über die Datei einlesen lasse, die .TXT sieht momentan so aus:

F ..-.
G --.
H ....
I ..
J .---
K -.-
L .-..
M --
N -.
O ---
P .--.
Q --.-
R .-.
S ...
T -
U ..-
V ...-
W .--
X -..-
Y -.--
Z --..
0 -----
1 .----
2 ..---
3 ...--
4 ....-
5 .....
6 -....
7 --...
8 ---..
9 ----.
. .-.-.-
, --..--
? ..--..

Wie füge ich am Ende den Key und den Value für die Leerzeichen ein ? Gibt es dafür überhuapt eine lösung
 

Neue Themen


Oben