LongGone LongGone - 3 months ago 33
Java Question

Morse Code Converter

I already posted a topic on this but have considerably (and that topic was put on hold..so I can't edit) changed my code (I tried what one of the users said in different variations, but no beans). I've tried running just toMorse, but although it compiles I get no output and an error message of

'java.lang.ArrayIndexOutOfBoundsException(at projmorsejava:22 and 46)'
I'm not sure how to configure toEnglish, at this point I've tried using the replaceAll, indexOf and valueOf methods. I've also tried using plaintextString but that also did not work out (I may have implemented it incorrectly).
Here is my revised code:

import java.util.Scanner;

public class ProjMorse
{
public static void main(String[] args) {
Scanner input = new Scanner(System.in);

String[] alpha = { "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", "1", "2", "3", "4", "5", "6", "7", "8",
"9", "0", " " };
String[] dottie = { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.",
"....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.",
"--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-",
"-.--", "--..", ".----", "..---", "...--", "....-", ".....",
"-....", "--...", "---..", "----.", "-----", "|" };

System.out
.println("Enter English to convert from English or Morse to convert from Morse:");

String ans = input.nextLine();

if (ans.equals("English")) {
System.out.println("Please enter the text you would like to convert to Morse Code: ");
String english = input.nextLine();

char[] translates = (english.toLowerCase()).toCharArray();
System.out.println(toMorse(translates, dottie)); //calls on method toMorse

}
else if (ans.equals("Morse")) {
System.out
.println("Please enter the text you would like to convert to English (separate words with '|'):");
String code = input.nextLine();

String[] translates = (code.split("[|]", 0));
System.out.println(toEnglish(translates, alpha));//calls on method toEnglish

}
else
System.out.println("Invalid input, please try again.");
}

public static String toMorse(char [] translates, String [] dottie)
{
String morse = "";
for (int j = 0; j < translates.length; j++)
{
char a = translates[j];
if(Character.isLetter(a))
{
morse = dottie[a + 'a'];
}
}
return morse;/*so I tried running only this(commented other stuff out) and it compiled but although it ran it didnt translate */
}

public static String toEnglish(String [] translates, String [] alpha)
{
String s;
for (int n = 0; n < translates.length; n++)
{
String a = translates[n];
s = java.util.Arrays.asList(alpha).(Character.toChars(a + 'a')[0]);//I'm not sure what to do here..
}
return s;
}
}

Answer

There are several things that do not work:

  1. missing initial public class ... (I suspect a copy-paste error)
  2. missing import java.util.Scanner; since you use Scanner
  3. wrong call to toMorse: first, two args are expected (check the method signature); then, first argument's name is not morse (unknown symbol), it must be translates, which you have just "created"! About the second: you need the array of strings that has in place of the e.g. "e" the morse code, so second argument must be... dottie
  4. wrong call to toEnglish: two args required (check the method signature, as done before!); the first, has to be translates, again (unknown s, as morse before)! About second argument: see above but of course since you have morse in input, you need the other array.
  5. in toMorse you pick each char using translates[j], not valueOf.
  6. similarly, in toEnglish you get the string using translates[n]
  7. in both toEnglish and toMorse, you have to "accumulate" the converted string into a string, and return it at the end, i.e. outside the loops!
  8. having a string, you pick the char at pos 0 using .charAt(0): to perform an op like x - 'a' x can't be a string, so since you have a string, you must get its first char.
  9. Note: about your using of morse and s: variable names in a method has nothing to do with variable names in the caller!

Example for toMorse:

    String morse = "";
    for (int j = 0; j < translates.length; j++)
    {
        char a = translates[j];
        if(Character.isLetter(a))
        {
            morse += dottie[a - 'a'];
        }
    }
    return morse;  // this symbol is unknown to the caller

You will call it with something as simple as

              System.out.println(toMorse(translates, dottie));

The fix for toEnglish is very similar (though your original code won't work), I hope you can do it by yourself.

I think is all, more or less.

Suggestion to fix toEnglish:

For each string you have in your translates array, you have to search into dottie string array in order to search for that particular sequence of dots and lines.

If you find it, the position (index) you find it at, it's also the index of the right letter you keep in the alpha array. So you might need to add that array as argument and use the index to pick the letter.

Or, rather, you can use the same "trick" you used to toMorse and keep the toEnglish method signature unchanged: once you have the index, since you have found it, you can "invert" the coding algorithm, so you have to add 'a' to that index (integer) to obtain the code for the letter.

You can use something like Character.toChars(k + 'a')[0] to take the char you want to add to the "accumulation string", being k the index.

The cumbersome notation Character.toChars(k + 'a')[0] is since indeed Character.toChars returns an array, so we pick the first element of that array, which is the char we need.