# Von Morsecode zu Text



## Lights (8. Okt 2018)

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 


```
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 (8. Okt 2018)

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 (8. Okt 2018)

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.

```
[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 (8. Okt 2018)

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 (9. Okt 2018)

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


----------



## MoxxiManagarm (9. Okt 2018)

Ergänze dir ein Mapping von "" auf ' '
Ein split über " " reicht aus, ein Element im Array (zwischen 2 ' ') ist "".


----------



## Lights (9. Okt 2018)

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 (9. Okt 2018)

```
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.


----------



## Lights (9. Okt 2018)

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




```
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();

    }

}
```


----------



## MoxxiManagarm (9. Okt 2018)

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 (9. Okt 2018)

Lights hat gesagt.:


> 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

```
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 (9. Okt 2018)

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 (9. Okt 2018)

Hier ein komplexeres Beispiel, damit der Kontext klarer wird:

```
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:

```
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 (9. Okt 2018)

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 (9. Okt 2018)

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


----------



## MoxxiManagarm (9. Okt 2018)

Ich würde daraus eine csv Datei (in deinem Fall ; getrennt) machen.


----------



## Lights (9. Okt 2018)

Stimmt, macht sinn, danke


----------

