0

I’m pulling out my hair… Yes, it’s posted all over and no, can’t seem to wrap my head around my error. I get that I’m trying to deal with the nuances of characters and strings. But my output is not helping so maybe someone else can? Below is the output I’m getting and the code that gives it to me.

Input:
...
no output

This input
... ---
output
e
e
e

and this input

...|---
output
e
e
e

Only the first morse "character" (which should be an 's'), ignores rest after the pipe and/or space

public static void morseToEnglish() {

    String englishArray[] = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};
    String morseArray[] = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".--- ", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."};

    //String translatedText = "";
    //String newEnglishChar;

    System.out.println("Enter Morse, separate each letter or digit with a single space, separate words with '|' ");
    Scanner input = new Scanner(System.in);

    String morseSentence = input.nextLine();

    String[] words = morseSentence.split("|");

    for (String word: words) {

    String[] morseChars = word.split(" ");

        for (String morseChar : morseChars) {

            if (morseChar.isEmpty()) { continue; }

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

                if (morseChar.equals(morseArray[i])) {

                    System.out.println(englishArray[i]);

                    //newEnglishChar = englishArray[i];
                    //translatedText = translatedText + newEnglishChar;
                }
            }
        }
    }
    //System.out.println(translatedText);
}

I'm not getting any compiling errors. The code works fine, I've just told it the wrong instructions so my output is not as I'd prefer. It seems to me that Scanner is inputting the morse, e.g. '...', and translating it as three e's not a single s. I had tried excepting cases (if(!.contains)) (more or less) but it was not working and seemed excessive conditions. I feel I am just not treating the correct objects in the correct manner. Really, I'd be fine if the second case (two morse characters, separated by a space) would function. A single morse character might be too much to ask at this point. The grand question: where am I telling Java it's ok to treat three dots as three separate letters? And why?...... I hope that is helpful.

SadieRose
  • 63
  • 1
  • 8
  • Welcome to Stack Overflow! It looks like you need to learn to use a debugger. Please help yourself to some [complementary debugging techniques](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). If you still have issues afterwards, please feel free to come back with a more specific question. – Joe C Oct 01 '17 at 21:04

2 Answers2

1

Your code has two issues:

  • Since | is a regex metacharacter, so you need to escape it using, for example, morseSentence.split("[|]"), and
  • You used wrong length in the inner loop: should be morseArray.length rather than words.length

All strings in the morseArray are unique, so you can set a break in the nested loop once you find a match.

Demo.

Note: You can benefit from an associative container to do the mapping without a loop (Map<K,V>).

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Ok, yes the data structure is sucky (@jeanr). I tend to clean it up (some) when/if I have the time. I prefer function over fashion. Though I am aware of instilling good practices. As for the two escapes and fixing the .length (I had that there at some point today lol) it is working fine. Good enough to turn in I thinks. Thank you all! – SadieRose Oct 01 '17 at 21:43
  • @bubblyBibliophile You are welcome. If you do not need additional help with this question, please accept one of the answers by clicking the gray check mark to the left of it. This would let others know that your problem is solved, and earn you a new badge on Stack Overflow. – Sergey Kalinichenko Oct 01 '17 at 21:46
1

There are several problems in the code you wrote.

  1. The data structure is not well chosen, for this use case, you should better use a Map because you are associating 2 values.

  2. The String you are using in your regex is not the good one, you need to escape it

  3. You can make your code more readable by avoiding to use local variables

Here is a working version of what you want

public static Map<String, String> init() {
    HashMap<String, String> map = new HashMap<>();
    map.put(".", "e");
    map.put("...", "h");
    //... All the other letters
    return map;
}

public static void main(String ... args) {
    Map<String, String> map = init();
    System.out.println("Enter Morse, separate each letter or digit with a single space, separate words with '|' ");
    Scanner input = new Scanner(System.in);
    String morseSentence = input.nextLine();
    for (String word: morseSentence.split("\\|")) {
        for (String morseChar : word.split(" ")) {
            if (!morseChar.isEmpty()) {
                System.out.print(map.get(morseChar));
            }
        }
        System.out.print(" ");
    }
}
jeanr
  • 1,031
  • 8
  • 15
  • Awesome answer... I had not looked into HashMap because I'm not sure if it's allowable" in class. (Sheesh). But, I'm going to teach myself and do it anyways. Uh... would a 2D array serve the same purpose as a HashMap? Something else I had been considering. – SadieRose Oct 01 '17 at 21:36
  • You can also do it using a 2D Array, but it will be less performant than using an HashMap (O(n) for 2D Array VS O(1) for HashMap). If this answer helped you, do not hesitate to mark your post as resolved @bubblyBibliophile :) – jeanr Oct 01 '17 at 21:55