两个数组或一个 HashMap 将字符串转换为摩尔斯电码?

Two arrays or one HashMap to convert a String to Morse code?

我正在尝试将字符串 String input; 转换为摩尔斯电码并返回。我很难弄清楚要使用哪种方法以及如何使用它。我正在尝试转换为摩尔斯电码的字符串:SOS,应转换为 ...---...,并将摩尔斯电码转换为英语:...---... - SOS.

我尝试过的一种方法是使用两个数组,String[] alpha = {A-Z0-9}String[] morse = {morse patterns}。然后我尝试将 String 输入拆分为一个数组,以将字符串输入中的每个字符与 String[] alpha 中的每个字符进行比较,并将每个索引存储在 indexArray[] 中。我用了 inputArray= input.split("", -1);

最后,通过一些 for 循环和 if 语句,我尝试使用我想查找字符串字符的索引,在 String[] morse 中查找莫尔斯电码。

我在上面尝试的方法不适用于单词,但适用于一个字符(下面的代码)。它失败了,我无法弄清楚如何以这种方式修复它。这甚至是最好的方法吗?或者 HashMap?

然后我尝试使用 HashMap 以英文字符为键,以莫尔斯码为值。

将英文字符串转换为摩尔斯电码和将摩尔斯电码转换为英文字符串的最佳方法是什么?数组还是 HashMap?

数组:

private 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", " "};

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

我正在处理的 for 循环中断了,不知道该怎么做:

public int[] indexOfArray(String englishInput) {
    englishArray = englishInput.split("", -1);
    for (int j = 0; j < englishArray.length; j++) {
        for (int i = 0; i < alpha.length; i++) {
            if (alpha[i].equals(englishArray[j])) {
                indexArray[i] = i;
            }
        }
    }
    return indexArray;
}

这只适用于一个字符(字符到莫尔斯码):

public int indexOfArrayOld(String englishInput) {
    for (int i = 0; i < alpha.length; i++) {
        if (alpha[i].equals(englishInput)) {
            indexOld = i;
        }
    }
    return indexOld;
}

public String stringToMorseOld(int dummyIndex) {
    String morseCo = morse[dummyIndex];
    return morseCo;
}

哈希图:

private static HashMap<String, String>; alphaMorse = new HashMap<String, String>();

static {
    alphaMorse.put("A", ".-");
    alphaMorse.put("B", "-...");
    alphaMorse.put("C", "-.-.");
    alphaMorse.put("D", "-..");
    alphaMorse.put("E", ".");
    alphaMorse.put("F", "..-.");
    alphaMorse.put("G", "--.");
    alphaMorse.put("H", "....");
    alphaMorse.put("I", "..");
    alphaMorse.put("J", ".---");
    alphaMorse.put("K", "-.-");
    alphaMorse.put("L", ".-..");
    alphaMorse.put("M", "--");
    alphaMorse.put("N", "-.");
    alphaMorse.put("O", "---");
    alphaMorse.put("P", ".--.");
    alphaMorse.put("Q", "--.-");
    alphaMorse.put("R", ".-.");
    alphaMorse.put("S", "...");
    alphaMorse.put("T", "-");
    alphaMorse.put("U", "..-");
    alphaMorse.put("V", "...-");
    alphaMorse.put("W", ".--");
    alphaMorse.put("X", "-..-");
    alphaMorse.put("y", "-.--");
    alphaMorse.put("z", "--..");
    alphaMorse.put("1", ".----");
    alphaMorse.put("2", "..---");
    alphaMorse.put("3", "...--");
    alphaMorse.put("4", "....-");
    alphaMorse.put("5", ".....");
    alphaMorse.put("6", "-....");
    alphaMorse.put("7", "--...");
    alphaMorse.put("8", "---..");
    alphaMorse.put("9", "----.");
    alphaMorse.put("0", "-----");
    alphaMorse.put(" ", "|");
}

我会想,理想情况下你有一个二维数组,例如:

    String[][] morseArray = new String[][] {{ "S" , "..." }, { "O", "---" }}; 

然后,如果您正在寻找速度和查找的便利性,您可能需要两个地图:

private Map<String,String> enToMorse;
private Map<String,String> morseToEn;

和一些私有方法来检索它们:

private Map<String,String> getMorseToEnMap() {
    if(morseToEn==null) {
        morseToEn = new HashMap<String,String>();
        for(String[] x : morseArray) {
            morseToEn.put(x[1], x[0]);
        }
    }
    return morseToEn;
}

那你就可以走了:

 Map<String,String> morse = getMorseToEn();
 String x = morse.get("...");
 [...]

好处是:一方面,您可以轻松定义映射 - 两个独立的数组很难保持同步 - 而另一方面,映射将是最快和最简单的查找类似内容的方法。

使用Hashmap 和get 方法比较它们,最后将键或值追加到字符串中:

public String stringToMorse(String str){
    String morse = "";
    for(char s: str.toCharArray()){
        morse += (String) Hashmap.get(s)+" ";
    }
    return morse;
}

对于另一个使用此方法而不是 get():

public static Object getKeyFromValue(Map hm, Object value) {
    for (Object o : hm.keySet()) {
      if (hm.get(o).equals(value)) {
        return o;
      }
    }
    return null;
}

效率方面我会推荐并行数组结构。 我对这些方法做了一个演示,我不是效率向导,所以嵌套循环在这里可能不太理想,或者我可能还有其他一些缺陷。

无论如何这里的例子class:

public class MorseTranslator {
private char[] 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',
        ' ' };//Changed this to char to save some memory and to help my methods :3

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

private String toMorse(String text) {
    char[] characters = text.toUpperCase().toCharArray();
    StringBuilder morseString = new StringBuilder();
    for (char c : characters) {
        for (int i = 0; i < alpha.length; i++) {
            if (alpha[i] == c) {
                morseString.append(morse[i]+" ");
                break; 
            }
        }
    }
    return morseString.toString();
}

private  String fromMorse(String text){
    String[] strings = text.split(" ");
    StringBuilder translated = new StringBuilder();
    for(String s : strings){
        for(int i=0; i<morse.length; i++){
            if(morse[i].equals(s)){
                translated.append(alpha[i]);
                break;
            }
        }
    }
    return translated.toString();
}

public MorseTranslator(){
    String input = "Hello there";
    String morse = toMorse(input);
    String translated = fromMorse(morse);
    System.out.println("Input: "+input);
    System.out.println("Morse: "+morse);
    System.out.println("Back From morse: "+translated);
}
}

上面的代码演示了一种可能的方法:-) 希望对您有所帮助。

既然你不说什么到底行不通,那我就只能猜了。也许问题是 String.equals() 方法区分大小写,即 "X" 和 "x" 不一样。但是,您似乎混合使用大写字母和非大写字母,所以这可能是问题所在。当您将 equals 替换为 equalsIgnoreCase 时,您的方法是否有效?

更多提示:

首先,不要使用字符串作为字符。您可以简单地使用可以容纳单个字符的 char

其次,不要使用两个数组来存储对象对的数组。维护两个数组既麻烦又容易出错。如果你想使用一个数组,那么定义一个 class 来保存一个字符和一个摩尔斯电码字符串,并定义一个包含这些的数组:

static class MorseMapping {
    char character;
    String morseCode;
    MorseMapping(char ch, String mc) {
        character = ch;
        morseCode = mc;
    }
}

static MorseMapping[] mappings = new MorseMapping[] {
    new MorseMapping('A', '.-'),
    \ etc.
}

第三,我个人不喜欢使用一张地图,因为从概念上讲,您不想在一个方向上绘制地图,而是在两个方向上绘制地图。相反,使用 两个 映射,一个从字符到莫尔斯码,一个从莫尔斯码到哈希映射。您可以按如下方式初始化它们:

static Map<String,Character> charToMorseMap;
static Map<Character,String> morseToCharMap;

private static void addPair(String morse, char ch) {
    charToMorseMap.put(ch, morse);
    morseToCharMap.put(morse, ch);
}

static {
    charToMorseMap = new HashMap<>();
    MorseToCharMap = new HashMap<>();
    // add all the characters
}

或者,您可以使用存在于各种开源 class 库中的 BiMap 实现,例如 Google Guava。

顺便说一句,你不能输入摩尔斯电码。例如, ”。 - 。”可能是字母 P,也可能表示 "AN"、"WE" 和许多其他字符串。所以,在将英文翻译成摩尔斯电码时,不要忘记添加空格来分隔字母。

在 class 中封装莫尔斯英语对,像这样:

public class EnglishMorseLetter {

  private String englishLetter;
  private String morseLetter;

public MorseLetter(String english, String morse){
    this.englishLetter = english;
    this.morseLetter = morse;
}

public String getEnglishLetter() {
    return englishLetter;
}
public void setEnglishLetter(String englishLetter) {
    this.englishLetter = englishLetter;
}
public String getMorseLetter() {
    return morseLetter;
}
public void setMorseLetter(String morseLetter) {        
    this.morseLetter = morseLetter;
}

}

在静态 class 中使用预定义值封装字典,如下所示:

public class Dictionary {

    private static List<MorseLetter> dictionary = new ArrayList<MorseLetter>();

    static {
        dictionary.add(new MorseLetter("", ""));
        dictionary.add(new MorseLetter("A", ".-"));
        dictionary.add(new MorseLetter("B", "-..."));
        dictionary.add(new MorseLetter("C", "-.-."));
        dictionary.add(new MorseLetter("D", "-.."));
        dictionary.add(new MorseLetter("E", "."));
        dictionary.add(new MorseLetter("F", "..-."));
        dictionary.add(new MorseLetter("G", "--."));
        dictionary.add(new MorseLetter("H", "...."));
        dictionary.add(new MorseLetter("I", ".."));
        dictionary.add(new MorseLetter("J", ".---"));
        dictionary.add(new MorseLetter("K", "-.-"));
        dictionary.add(new MorseLetter("L", ".-.."));
        dictionary.add(new MorseLetter("M", "--"));
        dictionary.add(new MorseLetter("N", "-."));
        dictionary.add(new MorseLetter("O", "---"));
        dictionary.add(new MorseLetter("P", ".--."));
        dictionary.add(new MorseLetter("Q", "--.-"));
        dictionary.add(new MorseLetter("R", ".-."));
        dictionary.add(new MorseLetter("S", "..."));
        dictionary.add(new MorseLetter("T", "-"));
        dictionary.add(new MorseLetter("U", "..-"));
        dictionary.add(new MorseLetter("V", "...-"));
        dictionary.add(new MorseLetter("W", ".--"));
        dictionary.add(new MorseLetter("X", "-..-"));
        dictionary.add(new MorseLetter("y", "-.--"));
        dictionary.add(new MorseLetter("z", "--.."));
        dictionary.add(new MorseLetter("1", ".----"));
        dictionary.add(new MorseLetter("2", "..---"));
        dictionary.add(new MorseLetter("3", "...--"));
        dictionary.add(new MorseLetter("4", "....-"));
        dictionary.add(new MorseLetter("5", "....."));
        dictionary.add(new MorseLetter("6", "-...."));
        dictionary.add(new MorseLetter("7", "--..."));
        dictionary.add(new MorseLetter("8", "---.."));
        dictionary.add(new MorseLetter("9", "----."));
        dictionary.add(new MorseLetter("0", "-----"));
        dictionary.add(new MorseLetter(" ", "|"));
    }


    public static MorseLetter english2Morse(MorseLetter letter){
        for(MorseLetter tempLetter : dictionary){
            if(letter.getEnglishLetter().equalsIgnoreCase(tempLetter.getEnglishLetter())){
                letter.setMorseLetter(tempLetter.getMorseLetter());
                break;
            }
        }

        return letter;

    }


    public static MorseLetter morse2English(MorseLetter letter){
        for(MorseLetter tempLetter : dictionary){
            if(letter.getMorseLetter().equalsIgnoreCase(tempLetter.getMorseLetter())){
                letter.setEnglishLetter(tempLetter.getEnglishLetter());
                break;
            }
        }

        return letter;

    }

}

对于 MCVE,我用 List 完成了它,但为了提高效率,我想建议使用两种不同的分类地图,分别是英语-莫尔斯对和莫尔斯-英语对。

也像这样把word封装在class里面:

public class EnglishMorseWord{

    private List<EnglishMorseLetter> word;

    public String getEnglishWord(){
        //...you combine your word property into english word
    }

    public void setEnglishWord(String englishWord){
        //...you parse your word and fill word property by using Dictionary
    }

    public String getMorseWord(){
        //...you combine your word property into morse word

    }

}

另一个好方法是使用 enum

public enum MorseCode {
    A('A', ".-"),
    B('B', "-..."),
    C('C', "-.-."),
    // ...
    D8('8', "---.."),
    D9('9', "----."),
    D0('0', "-----");

    private static final Map<String, MorseCode> FromCode = new HashMap<>(MorseCode.values().length);
    private static final Map<Character, MorseCode> FromChar = new HashMap<>(MorseCode.values().length);
    static {
        for (MorseCode value : values()) {
            FromCode.put(value.toCode(), value);
            FromChar.put(value.toChar(), value);
        }
    }

    public static MorseCode fromCode(String code) {
        return FromCode.get(code);
    }

    public static MorseCode fromChar(Character character) {
        return FromChar.get(character);
    }

    private final String Code;
    private final Character Character;
    private MorseCode(Character character, String code) {
        Code = code;
        Character = character;
    }

    public char toChar() {
        return Character;
    }

    public String toCode() {
        return Code;
    }
}