1

I have a morse code program that can encode. Now I want it to decode but I do not know how to replace a string of encrypted characters with the letter from my hash map.

Here is the method for decoding:

for(int i = 0; i < userInput.length(); i++){
        if(i != 0){
            morse.append(' ');
        }
        morse.append(codeLibrary.get(userInput.charAt(i))); //Currentely the same as encoding, this line needs to change
    }
    return morse.toString();

And here is my hashmap:

public static final java.util.Map<Character, String> codeLibrary;
 static{
    codeLibrary = new HashMap<>();
    codeLibrary.put('a',".-");      codeLibrary.put('b',"-...");
    codeLibrary.put('c',"-.-.");    codeLibrary.put('d',"-..");
    codeLibrary.put('e',".");       codeLibrary.put('f',"..-.");
    codeLibrary.put('g',"--.");     codeLibrary.put('h',"....");
    codeLibrary.put('i',"..");      codeLibrary.put('j',".---");
    codeLibrary.put('k',"-.-");     codeLibrary.put('l',".-..");
    codeLibrary.put('m',"--");      codeLibrary.put('n',"-.");  
    codeLibrary.put('o',"---");     codeLibrary.put('p',".--.");
    codeLibrary.put('q',"--.-");    codeLibrary.put('r',".-.");
    codeLibrary.put('s',"...");     codeLibrary.put('t',"-");
    codeLibrary.put('u',"..-");     codeLibrary.put('v',"...-");
    codeLibrary.put('w',".--");     codeLibrary.put('x',"-..-");
    codeLibrary.put('y',"-.--");    codeLibrary.put('z',"--..");
    codeLibrary.put('1',".----");   codeLibrary.put('2',"..---");
    codeLibrary.put('3',"...--");   codeLibrary.put('4',".----");
    codeLibrary.put('5',".....");   codeLibrary.put('6',"-....");
    codeLibrary.put('7',"--...");   codeLibrary.put('8',"---..");
    codeLibrary.put('9',"----.");   codeLibrary.put('0',"-----");
    codeLibrary.put(' ',"/");
  • 3
    If you're open to using Guava, you could use a [`BiMap`](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/HashBiMap.html). – Alexis King Aug 21 '14 at 15:37
  • This seems like it would have been the right thing to do. Thanks –  Aug 21 '14 at 15:43

2 Answers2

1

You would need a separate Map, one that is a Map<String, Character>, and again a HashMap<String, Character> would work well, fill it with el


If this is a school assignment, then I believe that this is the solution. If this is for real applications, then yeah, go ahead and use the Guava BiMap library as suggested by Jake King.


Edit
You ask:

This seems like a very long way of doing this. Is it not possible to insert the value to retrieve the key?

That's not how ordinary Maps work. You use the Key to get the Value, not the other way around. But this is not hard to do nor very "long". You could fill both Maps in the same loop even.


For example,...

import java.util.HashMap;
import java.util.Map;

public class MorseFun {
   public static final String[] LETTER_CODES = { ".-", "-...", "-.-.", "-..",
         ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.",
         "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--",
         "-..-", "-.--", "--.." };
   public static final String[] NUMBER_CODES = { "-----", ".----", "..---",
         "...--", ".----", ".....", "-....", "--...", "---..", "----." };

   private static Map<Character, String> charToCodeMap = new HashMap<>();
   private static Map<String, Character> codeToCharMap = new HashMap<>();

   public static void main(String[] args) {
      for (int i = 0; i < LETTER_CODES.length; i++) {
         char c = (char) ('a' + i);
         String s = LETTER_CODES[i];
         charToCodeMap.put(c, s);
         codeToCharMap.put(s, c);
      }

      for (int i = 0; i < NUMBER_CODES.length; i++) {
         char c = (char) ('0' + i);
         String s = LETTER_CODES[i];
         charToCodeMap.put(c, s);
         codeToCharMap.put(s, c);
      }



   }
}
Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • This seems like a very long way of doing this. Is it not possible to insert the value to retrieve the key? –  Aug 21 '14 at 15:38
  • 1
    @mungostrap: that's not how ordinary Maps work. You use the Key to get the Value, not the other way around. But this is not hard to do. You could fill both Maps in the same loop even. – Hovercraft Full Of Eels Aug 21 '14 at 15:39
  • 2
    @mungostrap A really inefficient and ugly way to do it without an external library would be to [iterate through the Map.Entry set](http://stackoverflow.com/q/46898/3735079) and equal the `Entry#getValue()` to retrieve the `Entry#getKey()`. But again, this is very bad, you should go for this answer solution. – Narmer Aug 21 '14 at 15:44
1

Just to play the devil's advocate you could just create a simple utility method that searches through a Map's Set<Entry> until it finds the value you need;

public static Character convertMorseToChar(String yourMorse){
    for(Map.Entry<Character,String> e : codeLibrary.entrySet()){
        if(e.getValue().equals(yourMorse)) return e.getKey();
    }
    return null;
}

All the above method does is runs an enhanced for loop, and loops over a Set collection of Entry objects gained from the Map using the .entrySet() method. Each Entry represents a Key/Value pair in the map. When it finds the Entry with the value you parsed into the method (your morse code), it returns that Entry's key (the character you are looking for).

I hope this helps.

Rudi Kershaw
  • 12,332
  • 7
  • 52
  • 77
  • I'm sorry, I am very new to Java and maps. Could you please explain what this is doing? –  Aug 21 '14 at 15:49
  • 1
    @mungostrap - Sure, no problem. I added in a brief description of the code and some links that should help you with any further reading you might need. – Rudi Kershaw Aug 21 '14 at 15:52
  • Thanks dude, i have opted to try Hovercrafts way –  Aug 21 '14 at 17:57