使用 HashMap 解码摩尔斯电码时出现问题。

Trouble decoding morse code using HashMaps.

我的代码可以很好地将常规文本编码为摩尔斯电码,但是当我尝试以另一种方式进行翻译时,我遇到了索引越界错误。不知道为什么?

import java.util.HashMap;
public class MorseCode {
private final String alphabet = "abcdefghijklmnopqrstuvwxyz0123456789 ";
private final String[] morse = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---",
        ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", ".----", "..---", "...--", "....-", ".....",
        "-....", "--...", "---..", "----.", "-----", "|"};
private HashMap<String, String> toText;
private HashMap<String, String> toCode;

public MorseCode() {
    toText = new HashMap<>();
    toCode = new HashMap<>();
    char[] alphaArray = alphabet.toCharArray();
    for(int i = 0; i < morse.length; i++) {
        toCode.put(morse[i], String.valueOf(alphaArray[i]));
        toText.put(String.valueOf(alphaArray[i]), morse[i]);
    }

}

public String encode(String s) {
    s = s.toLowerCase();
    String encoded = "";
    char[] chars = s.toCharArray();
    for(int i = 0; i < s.length(); i++) {
        for (HashMap.Entry<String, String> entry : toCode.entrySet()) {
            if (String.valueOf(chars[i]).equals(entry.getValue())) {
                encoded += entry.getKey() + " ";
            }
        }
    }

    return encoded;
}

public String decode(String s) {
    s = s.toLowerCase();
    String decoded = "";
    for(int i = 0; i < s.length(); i++) {
        for (HashMap.Entry<String, String> entry : toText.entrySet()) {
            if (morse[i].equals(entry.getValue())) {
                decoded += entry.getKey();
            }
        }
    }

    return decoded;
}

}

试图找到一个双管齐下的解决方案,任何 help/advice 将不胜感激!

我测试了这段代码,它可以正常工作。请注意,这是一个非常初级的实现,但适当地使用了 HashMap class 的一些便利。我强烈建议您 运行 在调试模式下跟踪变量的值。

import java.util.HashMap;

public class MorseCode {

    //Constants hold the accepted characters
    private final String alphabet = "abcdefghijklmnopqrstuvwxyz0123456789 ";
    private final String[] morse = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---",
        ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", ".----", "..---", "...--", "....-", ".....",
        "-....", "--...", "---..", "----.", "-----", "|"};

    //Maps map the code to text and text to code
    private HashMap<String, String> toText;
    private HashMap<String, String> toCode;

    //Problem: toText had text as keys. Keys should be used to identify the value your want to get.
    //Solution: swapped toText logic to toCode logic
    public MorseCode() {
        toText = new HashMap<>();
        toCode = new HashMap<>();
        char[] alphaArray = alphabet.toCharArray();
        for(int i = 0; i < morse.length; i++) {
            toText.put(morse[i], String.valueOf(alphaArray[i]));
            toCode.put(String.valueOf(alphaArray[i]), morse[i]);
        }
    }

    //Problem: kind of complicated logic. Was working, but did not need all that truncation
    //Solution: HashMap contains neat methods to work with keys - get(key) and containsKey(key)
    //In this solution, if the key is not found, we print the plain text character
    public String encode(String s) {
        s = s.toLowerCase();
        String encoded = "";
        for(int i = 0; i < s.length(); i++) {
            String c = String.valueOf(s.charAt(i));
            if (toCode.containsKey(c)) {
                encoded += toCode.get(c) + " ";
            } else {
                encoded += c;
            }
        }
        return encoded;
    }

    //Problem: logic was broken. Again, you are mapping the key to the value you want in toText, so use it.
    //Solution: Same logic than the encode method, but we had to strip off the spaces
    public String decode(String s) {
        String[] code = s.split(" ");
        String decoded = "";
        for(int i = 0; i < code.length; i++) {
            if (toText.containsKey(code[i])) {
                decoded += toText.get(code[i]);
            } else {
                decoded += "?";
            }
        }
        return decoded;
    }
}

main方法中的测试代码。这个测试应该真正考虑所有边界情况(特殊字符、多个空格、空字符串等)并将输入与预期输出进行比较。但为时已晚。 :-)

public class Main {
    public static void main(String[] args) {
        MorseCode m = new MorseCode();
        String encoded = m.encode("Unencoded Text");
        String decoded = m.decode("..- -. . -. -.-. --- -.. . -.. | - . -..- - ");
        System.out.println(encoded);
        System.out.println(decoded);

    }
}

干杯。