# Morse Code decoder



## NicoBec (11. Jan 2018)

Hi,

ich habe die Aufgabe einen encoder und einen decoder für Morse Codes zu schreiben. 

Der Encoder war kein Problem: ich habe mir den String als char array ausgeben lassen und bin dann über jeden Index gegangen und habe ihn mit verglichen und mit switch() geändert. 

Doch funktioniert dieses Prinzip auch beim decoden. Ich gebe der Methode ja einen Morsecode. Wenn ich daraus ein array von "." und "-". Diese kann ich ja jetzt schlecht abgleichen, da z.B. das "A" ein ".-" und ich nur ein Zeichen in dem char array habe. 

Meine Idee bis jetzt dazu:


```
public static String decode(String input) {
       
        String codeTwo = "";
        char charactersTwo[] = input.toUpperCase().toCharArray();

        for (int i = 0; i < charactersTwo.length; i++) {

            switch (charactersTwo[i]) {
            case ".-":
                codeTwo += "A";
                break;
            case '-'+'.'+'.'+'.':
                codeTwo += "B";
                break;
            case '-'+'.'+'-'+'.':
                codeTwo += "C";
                break;
            case '-'+'.'+'.':
                codeTwo += "D";
                break;
            case '.':
                codeTwo += "E";
                break;
            case '.'+'.'+'-'+'.':
                codeTwo += "F";
                break;
```

Ich hoffe, ich konnte verständlich machen, was ich meine.


----------



## Robat (11. Jan 2018)

- hier stand quatsch - 
hab ich verlesen.


----------



## Javinner (11. Jan 2018)

@NicoBec 
Schau dir das hier an, am Anfang geht es um dieses Thema
https://www.java-forum.org/thema/wachsen-mit-dem-buch-java-ist-auch-eine-insel.178873/


----------



## NicoBec (11. Jan 2018)

@Javinner Danke dir. (Y)


----------



## AndiE (11. Jan 2018)

ich denke, dass das so einfach nicht geht. Nehmen wir mal die Anzahl der Zeichen (. und -), dann ergibt sich:
1 Zeichen= e und m (2 Zeichen)
2 Zeichen= i , a, n, m (4 Zeichen)
3 Zeichen =s, ..., o(8 Zeichen)
4 Zeichen= h... ,ch (16 Zeichen)

Das muss umgesetzt werden. Und das geht nicht so einfach mit switch.


----------



## NicoBec (11. Jan 2018)

Okey, nochmal ein kleines Update:

Das hier sind meine Methoden: 


```
public static String encode(String input) {

        String code = "";
        char characters[] = input.toUpperCase().toCharArray();

        for (int i = 0; i < characters.length; i++) {

            switch (characters[i]) {
            case 'A':
                code += ".- ";
                break;
            case 'B':
                code += "-... ";
                break;
            case 'C':
                code += "-.-. ";
                break;
            case 'D':
                code += "-.. ";
                break;
            case 'E':
                code += ". ";
                break;
            case 'F':
                code += "..-. ";
                break;
            case 'G':
                code += "--. ";
                break;
            case 'H':
                code += ".... ";
                break;
            case 'I':
                code += ".. ";
                break;
            case 'J':
                code += ".--- ";
                break;
            case 'K':
                code += "-.- ";
                break;
            case 'L':
                code += ".-.. ";
                break;
            case 'M':
                code += "-- ";
                break;
            case 'N':
                code += "-. ";
                break;
            case 'O':
                code += "--- ";
                break;
            case 'P':
                code += ".--. ";
                break;
            case 'Q':
                code += "--.- ";
                break;
            case 'R':
                code += ".-. ";
                break;
            case 'S':
                code += "... ";
                break;
            case 'T':
                code += "- ";
                break;
            case 'U':
                code += "..- ";
                break;
            case 'V':
                code += "...- ";
                break;
            case 'W':
                code += ".-- ";
                break;
            case 'X':
                code += "-..- ";
                break;
            case 'Y':
                code += "-. ";
                break;
            case 'Z':
                code += "--.. ";
                break;
            case ' ':
                code += "\r\n";
                break;

            }
        }

        return code;

    }

    /**
     * Returns a new string which is the natural-language version of the input
     * string, which is assumed to be in Morse code format as produced by the
     * encode method.
     *
     * @param input
     *            Morse code input string.
     * @return natural language version or {@code null} if the input string
     *         could not be properly parsed.
     */
    public static String decode(String input) {
       
        String codeTwo = input;
        String[] output = input.split(" ");

        for (int i = 0; i < output.length; i++) {
           
            switch (output[i]) {
            case ".-":
                codeTwo += "A";
                break;
            case "-...":
                codeTwo += "B";
                break;
            case "-.-.":
                codeTwo += "C";
                break;
            case "-..":
                codeTwo += "D";
                break;
            case ".":
                codeTwo += "E";
                break;
            case "..-.":
                codeTwo += "F";
                break;
            case "--.":
                codeTwo += "G";
                break;
            case "....":
                codeTwo += "H";
                break;
            case "..":
                codeTwo += "I";
                break;
            case ".---":
                codeTwo += "J";
                break;
            case "-.-":
                codeTwo += "K";
                break;
            case ".-..":
                codeTwo += "L";
                break;
            case "--":
                codeTwo += "M";
                break;
            case "-.":
                codeTwo += "N";
                break;
            case "---":
                codeTwo += "O";
                break;
            case ".--.":
                codeTwo += "P";
                break;
            case "--.-":
                codeTwo += "Q";
                break;
            case ".-.":
                codeTwo += "R";
                break;
            case "...":
                codeTwo += "S";
                break;
            case "-":
                codeTwo += "T";
                break;
            case "..-":
                codeTwo += "U";
                break;
            case "...-":
                codeTwo += "V";
                break;
            case ".--":
                codeTwo += "W";
                break;
            case "-..-":
                codeTwo += "X";
                break;
            case "-.--":
                codeTwo += "Y";
                break;
            case "--..":
                codeTwo += "Z";
                break;

            }
    }
           
            return codeTwo;
        }
}
```

Für den Morsecode soll für jedes Wort eine Zeile wiedergegeben werden, deshalb das 
case ' ':
                code += "\r\n";
                break;
am Ende. 
Genau das sorgt jetzt aber dafür, dass bei der zweiten Methode bei jedem folgenden String der Anfangsbuchstabe vergessen wird. 

Aus "hello world" (in Morsecode) macht die decode Methode 
"helloorld" weil das der Punkt ist, an dem der Zeilenumbruch stattfindet.

Habt ihr für dieses Problem Lösungsvorschläge?


----------



## Javinner (11. Jan 2018)

NicoBec hat gesagt.:
			
		

> Genau das sorgt jetzt aber dafür, dass bei der zweiten Methode bei jedem folgenden String der Anfangsbuchstabe vergessen wird


las \r weg
Allgemein ist die Umwandlung von String zum char-Array ein Schritt zu viel. 

```
for(int i = 0; i < input.length(); i++)
{
      switch(input.charAt(i))
      {
           //Dein Code
       }
}
```
Ebenso hätte ich mir den switch() erspart. Hier wäre Map oder zwei Arrays mit jeweils Morsezeichen und Buchstaben (was einem besser liegt) mMn. wesentlich geeigneter und vor allem platzsparender und übersichtlicher.


----------



## Blender3D (12. Jan 2018)

```
public class MorseCoder {
    final static String[] codeAlphabet = { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-",
            ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.", "--.." };

    /**
     * Translates code letter to alphabet letter.
     *
     * @param codeLetter
     * @return Character or null.
     */
    public static Character codeLetterToAlpha(String codeLetter) {
        for (int i = 0; i < codeAlphabet.length; i++) {
            if (codeLetter.equals(codeAlphabet[i]))
                return (char) ((int) ('A') + i);
        }
        return null; // if codeLetter was not a code string
    }
    public static String decode(String input) {
        StringBuffer code = new StringBuffer();
        String[] words = input.split("\n"); // split to words
        for (int i = 0; i < words.length; i++) {
            String[] letters = words[i].split(" "); // split words to letters
            for (int ii = 0; ii < letters.length; ii++) {
                Character c = codeLetterToAlpha(letters[ii]);
                if (c == null) // ignore invalid input
                    continue;
                code.append(c);
            }
            if (i < words.length - 1) // add space if sentence is not finished
                code.append(' ');
        }
        return code.toString();
    }
    public static String encode(String input) {
        input = input.toUpperCase();
        StringBuffer code = new StringBuffer();
        int startAlphabet = Character.getNumericValue('A');
        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            if (c != ' ' && (c < 'A' || c > 'Z'))
                continue;
            code.append(c == ' ' ? '\n' : codeAlphabet[Character.getNumericValue(c) - startAlphabet] + ' ');
        }
        return code.toString();
    }
}
```


```
String code = MorseCoder.encode("hello world");
        System.out.println(code);
        System.out.println();
        System.out.println(MorseCoder.decode(code));
```
Schau Dir mal die Variante an!


----------



## Blender3D (12. Jan 2018)

```
public class MorseCoder {
    final static String[] codeAlphabet = { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-",
            ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.", "--.." };

    /**
     * Translates alphabet letter to code letter.
     *
     * @param c
     * @return String
     */
    public static String alphaToCodeLetter(char c) {
        if (c < 'A' || c > 'Z')
            return "";
        return codeAlphabet[Character.getNumericValue(c) - Character.getNumericValue('A')];
    }

    /**
     * Translates code letter to alphabet letter.
     *
     * @param codeLetter
     * @return Character or null.
     */
    public static Character codeLetterToAlpha(String codeLetter) {
        for (int i = 0; i < codeAlphabet.length; i++) {
            if (codeLetter.equals(codeAlphabet[i]))
                return (char) ((int) ('A') + i);
        }
        return null; // if codeLetter was not a code string
    }

    public static String decode(String input) {
        StringBuffer code = new StringBuffer();
        String[] words = input.split("\n"); // split to words
        for (int i = 0; i < words.length; i++) {
            String[] letters = words[i].split(" "); // split words to letters
            for (int ii = 0; ii < letters.length; ii++) {
                Character c = codeLetterToAlpha(letters[ii]);
                if (c == null) // ignore invalid input
                    continue;
                code.append(c);
            }
            if (i < words.length - 1) // add space if sentence is not finished
                code.append(' ');
        }
        return code.toString();
    }

    public static String encode(String input) {
        input = input.toUpperCase();
        StringBuffer code = new StringBuffer();
        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            code.append(c == ' ' ? '\n' : alphaToCodeLetter(c) + ' ');
        }
        return code.toString();
    }
}
```
Etwas übersichtlicher formuliert.


----------



## NicoBec (12. Jan 2018)

@Blender3D Danke dir für den Code. Hättest du bezüglich meines Codes gar keine Idee?


----------

