1

I am working on a simple Morse Code translator for my Intro to Programming class. This is a very simple design based on the techniques I have been taught.

This program works for a single character conversion, but cannot do words or sentences. I believe the problem has to do with the morse[index] statement at the end, but I can't figure out how to print the translated text as a whole.

public class Exercise12_9
{
    public static void main(String[] args)
    {
        String[] english = { "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[] morse = { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", 
                ".---", "-.-", ".-..", "--", "-.", "---", ".---.", "--.-", ".-.",
                "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", ".----",
                "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.",
                "-----", "--..--", ".-.-.-", "..--.." };


        Scanner keyboard = new Scanner(System.in);

        String userInput;

        int index;

        index = 0;

        System.out.println(" This is an English to Morse Code Translator.  ");
        System.out.println(" Please enter what you would like translate ");
        System.out.println("             into Morse Code. ");
        System.out.println(" ============================================ ");

        userInput = keyboard.next();

        userInput = userInput.toLowerCase();

        for (index = 0; index < userInput.length(); index++)           
        {
            char [] chars = userInput.toCharArray();

            if (userInput.equals(english[index]))
            {    
                System.out.println(" Translated : " + morse[index]);       
            }
        }  
    }
}
psubsee2003
  • 8,563
  • 8
  • 61
  • 79
Derek Boeka
  • 13
  • 1
  • 1
  • 3

7 Answers7

2

You've got a couple things here that need to be addressed, so lets take a look:

Input

Scanner.next() is only going to give only the next token. In your case, you want the entire string. Try using Scanner.nextLine() instead.

Translator Logic

The way your code exists currently, you are stepping through the input (correct), but for each character in the input, you're not fetching the equivalent in Morse Code! You're instead comparing the entire input to the single English character at english[index]. See below for a suggestion to fix your logic.

Output

Also notice that you are printing out a translated String after each character, which I don't think you want to do.

Suggestions

Couple of suggestions for you:

  1. If you want to handle a space character in the input, add that to your arrays!
  2. I would highly suggest storing your English and Morse characters in a Map. This way, you can very easily look up the Morse equivalent to an English character. Your arrays are ok still if you would like, but perhaps add the following after they're initialized:

    final Map<String, String> mapping = new HashMap<String, String>();
    for (int i = 0; i < english.length; ++i) {
        mapping.put(english[i], morse[i]);
    }
    

    Now with this, you can look up the Morse character in your loop using mapping.get(String.valueOf(userInput.charAt(index))).

  3. To build up your output, I would recommend using StringBuilder. So for each iteration in your loop, builder.append(...), and when you're ready to print it out, you can use builder.toString()

This was definitely an answer better-suited for a code review, but hey, it answered your logic issue. Hope this helps!

avojak
  • 2,342
  • 2
  • 26
  • 32
2

Here is the Optimized Code of your Given Solution

public class MorseCode {
    public static Scanner sc;
    public static void main(String args[]) throws IOException  //Input Output Exception is added to cover the BufferedReader 
    {
        int option = 0;
        String sentence = "",answer = "",answer1 = "";
         char[] english = { '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',
                 ',', '.', '?' };   //Defining a Character Array of the English Letters numbers and Symbols so that we can compare and convert later 

         String[] morse = { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", 
                    ".---", "-.-", ".-..", "--", "-.", "---", ".---.", "--.-", ".-.",
                    "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", ".----",
                    "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.",
                    "-----", "--..--", ".-.-.-", "..--.." };  //Defining an Array of String to hold the Morse Code value of Every English Letter,Number and Symbol in the same order as that of the character Array  
        sc = new Scanner(System.in);
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println(">>>>Welcome to MorseCode Software<<<<");
        System.out.println("");
        do
        {
        System.out.println("-->Enter the Option Corresponding to the Task you want to Perform ");
        System.out.println("->1.Generate Morse Code<- OR ->2.Generate English Language<- OR ->3.Exit ");
        System.out.print("->");
        while(!sc.hasNextInt())  //Repeat Until the next Item is an Integer i.e Until the Next Item is an Integer Keep on Repeating it 
        {//NOTE- The hasnext() function is also used when we are using the Iterator where the next input is always checked and then if it is valid it is allowed to be entered 
            System.out.println("");
            System.err.println("-->ERROR<-->Enter Digits Only<--");
            System.out.print("->");
            sc.next();   //Repeat and Discard the previous Inputs which are not valid 
        }
        option = sc.nextInt();
        switch(option)
        {
        case 1:
        {
            System.out.println("");
            System.out.println("-->Enter the Sentence that you want to Transmit Using the Morse Code ");
            System.out.print("->");
            sentence = br.readLine();
            System.out.println("");
            sentence = sentence.toLowerCase(); //Because morse code is defined only for the lower case letters and the numbers and the Symbols will remain the Same
            char[] morsec = sentence.toCharArray();
            for(int i = 0; i < morsec.length;i++)  //The loop will run till i is less than the number of characters in the Sentence because Every Character needs to Be Converted into the Respective Morse Code 
            {//For Every Letter in the User Input Sentence
                for(int j = 0;j<english.length;j++)   //For Every Character in the morsec array we will have to traverse the entire English Array and find the match so that it can be represented 
                {
                    if(english[j] == morsec[i])  //If the Character Present in English array is equal to the character present in the Morsec array then Only Execute 
                    {//Always remember that the condition in the Inner loop will be the first to be Equated in the If Statement because that will change until the characters match 
                        answer = answer + morse[j] + " ";  //After Every Letter is generated in the Morse Code we will give a Space 
                    }  //Since the Letters in the English char and the symbols present in the morse array are at the Same Index 
                }
            }
            System.out.println("-->The Morse Code Translation is:- ");
            System.out.print(">> ");
            System.out.println(answer);
            System.out.println("");
            break;
        }
        case 2:
        {
            System.out.println("");
            System.out.println("-->Enter the Morse Code and After Every Letter add Space in Between ");
            System.out.print("-> ");
            sentence = br.readLine();
            System.out.println("");
            String[] morsec = sentence.split(" ");   //To use the split function to Convert Every Morse Code String as a Separate Entry in the STring array 
            for(int i = 0;i < morsec.length;i++)
            {//For Every morse code Letter Entered 
            //Remember - We are Splitting on the Basis of the space     
                for(int j = 0;j < morse.length;j++)
                {
                    if(morse[j].equals(morsec[i]))  //When you are comparing the String you have to Do this and not == 
                    {
                        answer1 = answer1 + english[j];  //Since the characters in the Morse array and the English Array are in the Same Index
                    }
                }
            }
            System.out.println("-->The English Language Translation is:- ");
            System.out.print(">> ");
            System.out.println(answer1);
            System.out.println("");
            break;
        }
        case 3:
        {
            System.out.println("");
            System.out.println(">>Thank you For Using this Service<<");
            System.out.println("");
            break;
        }
        default:
        {
            System.err.println("-->ERROR<-->Invalid Option Entered<--");
            System.out.println("");
            break;
        }
        }
        }
        while(option!=3);
        }

}
piet.t
  • 11,718
  • 21
  • 43
  • 52
Radhesh Khanna
  • 141
  • 3
  • 11
1

I think this can be your solution.

Scanner keyboard = new Scanner(System.in);
    String  userInput = keyboard.nextLine();

    String output;
    for (index = 0; index < userInput.length(); index++)           
      {
         if (Arrays.asList(english).contains(userInput[index]))
         {        
             output+=morse[index];
         }
      } 
    System.out.println(" Translated : " +  output); 
Diptopol Dam
  • 823
  • 1
  • 10
  • 39
1

I believe you are trying to achieve something like this. You were on a good path, although you need to take a look at a few pointers I have for your code.

  1. first of all you created an array of String for the alphanumeric in english. Since you take an input from user and split it in char, you should have created an array of char instead. Since you were trying to compare user input with your array, you were using something.equals(something else) --> this is a method for String.. Now that you have two character to compare use the == comparision sign.
  2. It is good practice to initiate a variable and declare it's starting value on the same line (less line of code). Same thing goes for the for loop, initiate the index variable directly in the loop declaration. (Usually starting with letter i instead of the variable index).
  3. The double for loop at the end is necessary to compare every character from the input to every character of your english letters and numbers.
  4. For the answer suggested below, I used a String str to concatenate the morse value. Then you simply have to print out it's value.

Although I modified a bit your code, play around with with and see the different outputs it creates, this is the best way to learn from the code given.

Good luck with the learning

public static void main(String[] args){

    char[] english = { '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[] morse = { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", 
                ".---", "-.-", ".-..", "--", "-.", "---", ".---.", "--.-", ".-.",
                "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", ".----",
                "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.",
                "-----", "--..--", ".-.-.-", "..--.." };

    //Scanner keyboard = new Scanner(System.in);

    System.out.println(" This is an English to Morse Code Translator.  ");
    System.out.println(" Please enter what you would like translate ");
    System.out.println("             into Morse Code. ");
    System.out.println(" ============================================ ");

    //String userInput = keyboard.nextLine().toLowerCase();
    String userInput = "TEST".toLowerCase();

    char[] chars = userInput.toCharArray();

    String str = "";
    for (int i = 0; i < chars.length; i++){
        for (int j = 0; j < english.length; j++){

            if (english[j] == chars[i]){
                str = str + morse[j] + " ";  
            }
        }
    }
    System.out.println(str);
} 
qcGold
  • 200
  • 2
  • 12
  • Thank you very much! The steps you gave me helped alot not only with the actual code but also understanding why those steps are needed. I really appreciate the pointers! – Derek Boeka Apr 17 '15 at 19:19
1

If you're after two-way translator (Morse <=> English) and you prefer Java Stream approach then I think it's better to keep the English characters array as String rather than char - this is due to slightly difficult mapping of chars in a Stream (this question for reference) which would make the Stream approach a bit more cluttered.

public class MorseCode {

    private static final String[] english = {
        "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",
        ",", ".", "?", "!", ":", "@", "=", "-", "+", "\"", "/", "&",
        "'", "(", ")"
    };

    private static final String[] morse = {
        ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..",
        ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.",
        "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", ".----",
        "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.",
        "-----", "--..--", ".-.-.-", "..--..", "-.-.--", "---...", ".--.-.",
        "-...-", "-....-", ".-.-.", ".-..-.", "-..-.", ".-...", ".----.",
        "-.--.", "-.--.-"
    };

    private static final Map<String, String> EN_TO_MORSE = new HashMap<>();
    private static final Map<String, String> MORSE_TO_EN = new HashMap<>();

    static {
        for (int i = 0; i < english.length; i++) {
            EN_TO_MORSE.put(english[i], morse[i]);
            MORSE_TO_EN.put(morse[i], english[i]);
        }
    }

    public static void main(String[] args) {

        String output;

        output = MorseCode.run(false, "Hello, World!");
        System.out.println(output); // .... . .-.. .-.. --- --..-- / .-- --- .-. .-.. -.. -.-.--

        output = MorseCode.run(true, ".... . .-.. .-.. --- --..-- / .-- --- .-. .-.. -.. -.-.--");
        System.out.println(output); // hello, world!
    }

    private static String run(boolean codeToEnglish, String input) {

        if (input == null || input.length() == 0)
            throw new IllegalArgumentException("Invalid input");

        String wordSplitter, wordJoiner, charSplitter, charJoiner;
        Map<String, String> mapper;
        
        if (codeToEnglish) {
            wordSplitter = " / ";
            wordJoiner = " ";
            charJoiner = "";
            charSplitter = " ";
            mapper = MORSE_TO_EN;
        } else {
            wordSplitter = " ";
            wordJoiner = " / ";
            charJoiner = " ";
            charSplitter = "";
            mapper = EN_TO_MORSE;
        }

        return Arrays
            .stream(input.trim().toLowerCase().split(wordSplitter))
            .map(word -> createWord(word, charJoiner, charSplitter, mapper))
            .collect(Collectors.joining(wordJoiner));
    }

    private static String createWord(String word, String joiner, String splitter, Map<String, String> mapper) {
        return Arrays.stream(word.split(splitter)).map(mapper::get).collect(Collectors.joining(joiner));
    }

}
Martin
  • 1,460
  • 1
  • 13
  • 17
0

if you look in the java documentation at Scanner.Next() you'll notice that next only returns the next token. use Scanner.nextLine() to get a line of text instead of just a single token.

Gelunox
  • 772
  • 1
  • 5
  • 23
  • Thanks for the help! I fixed that line (Stupid error I will admit) and the output is the same. I understand that the for loop is stepping through the user input and I feel that the display portion needs to be outside of the for statement. Do I need to store the translated text into an array and then print the contents of the array? I apologize for my lack of knowledge on this, my school has a great program for coding, it just teaches in very small simple steps and leaves alot to discovery. Thanks again for the comment! – Derek Boeka Apr 17 '15 at 18:42
0

You need to loop through every char of the user input and then loop through the English chars to find where the user input char is located in english. Once found use the same index from english in morse. I am assuming english and morse have same length and morse[0] is the translation of english[0] in morse code.

userInput = userInput.toCharArray();
for (index = 0; index < userInput.length; index++) { 
     for (int i = 0; i < english.length; i++) {
         if (userInput[index] == english[i]) {
             System.out.println(" Translated : " + morse[i]);
         {
     }
}  

You also need to use Scanner.nextLine() for user input as @WhiteNightFury suggested.

Code Whisperer
  • 1,041
  • 8
  • 16