Java 破译莫尔斯电码时出错

Java 破译莫尔斯电码时出错,java,string,morse-code,Java,String,Morse Code,我正在试着把一个给定的莫尔斯电码译成英语。然而,我写的代码中有一个bug。这是我的密码: String code=".... . -.-- .--- ..- -.. ."; //Decodes to "HEY JUDE" String[] letters = code.split(" "); StringBuilder res = new StringBuilder(); for(String str : letters){ if(!str.equals("")) r

我正在试着把一个给定的莫尔斯电码译成英语。然而,我写的代码中有一个bug。这是我的密码:

String code=".... . -.--   .--- ..- -.. ."; //Decodes to "HEY JUDE"
String[] letters = code.split(" ");
StringBuilder res = new StringBuilder();
for(String str : letters){
    if(!str.equals(""))
        res.append(MorseCode.get(str));
    else res.append(" ");
}
System.out.println(res);
在第7行,如果我写:

res.append(" ");
res.append("");
输出为:

嘿,裘德

如果我写:

res.append(" ");
res.append("");
输出为:

海朱德


围绕空格拆分的三个连续空格将提供两个空字符串(第一个和第二个连续空格之间的空字符串加上第二个和第三个连续空格之间的空字符串)

您需要更改消息空间的编码方式,或者处理这两个连续的空字符串。假设您无法更改消息的编码,并且空格总是单独出现(字母分隔符)或按三个空格出现(编码空格),则以下操作将起作用:

String code=".... . -.--   .--- ..- -.. ."; //Decodes to "HEY JUDE"
Iterator<String> letters = Arrays.asList(code.split(" ")).iterator();
StringBuilder res = new StringBuilder();
while(letters.hasNext()) {
    String current = letters.next();
    if (! "".equals(current)) { // we have a letter
        res.append(MorseCode.get(current));
    } else { // we have an empty string, the first of two which represent a space
        res.append(" ");
        letters.next(); // we skip the next item which will be an empty string
    }
}
System.out.println(res);
String code=“//解码为“嘿,裘德”
迭代器字母=Arrays.asList(code.split(“”).Iterator();
StringBuilder res=新的StringBuilder();
while(letters.hasNext()){
当前字符串=字母。下一步();
如果(!“”.equals(current)){//我们有一个字母
res.append(MorseCode.get(current));
}else{//我们有一个空字符串,两个字符串中的第一个表示一个空格
决议附件(“”);
letters.next();//我们跳过下一项,它将是一个空字符串
}
}
系统输出打印项次(res);

您可以(字母表示为
x
,因为我没有您的莫尔斯电码类)。

如果您使用
地图作为字典,您可以这样做。将
null
值替换为
'
,并跟踪循环中之前打印的
char
,以便只打印一个空格字符

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MorseCode {

    static Map<String, Character> morseDictionary;

    public static void main(String[] args) {
        morseDictionary = new HashMap<String, Character>();
        morseDictionary.put("....", 'H');
        morseDictionary.put(".", 'E');
        morseDictionary.put("-.--", 'Y');
        morseDictionary.put(".---", 'J');
        morseDictionary.put("..-", 'U');
        morseDictionary.put("-..", 'D');

        String morseCode = ".... . -.--   .--- ..- -.. .";
        printTranslationOf(morseCode);
    }

    public static void printTranslationOf(String morseCode) {

        String[] singleCharacters = morseCode.split(" ");

        List<Character> latinCharacters = new ArrayList<Character>();

        char lastChar = ' ';
        for (String character : singleCharacters) {
            char printable = morseDictionary.get(character) == null ?
                    ' ' : morseDictionary.get(character);

            if (printable == ' ') {
                if (lastChar != ' ') {
                    latinCharacters.add(printable);
                }
            } else {
                latinCharacters.add(printable);
            }

            lastChar = printable;
        }

        latinCharacters.forEach((Character character) -> {
            System.out.print(character);
        });
    }
}
import java.util.ArrayList;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
公共类莫尔斯电码{
静态地图;
公共静态void main(字符串[]args){
morseDictionary=newhashmap();
morseDictionary.put(“…..”,“H”);
穆尔斯迪科.普特(“.”,“E”);
morseDictionary.put(“-.-”,“Y”);
穆尔斯迪科.普特(“.-”,“J”);
morseDictionary.put(“…-”,U');
morseDictionary.put(“-…”,D');
字符串morseCode=“……-…-”;
打印翻译f(摩尔斯电码);
}
公共静态无效打印转换(字符串莫尔斯码){
String[]singleCharacters=morseCode.split(“”);
List latinCharacters=新的ArrayList();
char lastChar='';
用于(字符串:单个字符){
char printable=morseDictionary.get(character)==null?
'':morseDictionary.get(字符);
如果(可打印=“”){
如果(lastChar!=''){
拉丁字符。添加(可打印);
}
}否则{
拉丁字符。添加(可打印);
}
lastChar=可打印;
}
拉丁字符。forEach((字符)->{
系统输出打印(字符);
});
}
}

我不知道您为什么要用一个循环来解决这个问题。更简单且可能更可读的解决方案是

  • 在3个空格上拆分
    code
    ,以获得所有单独的编码“单词”,如
    “…-”
    “…-…-”
  • 将每个编码的“字”在一个空格中拆分,以获得单个莫尔斯电码序列
  • 那你可以

    • 将摩尔斯电码转换为字母
    • 将解码的字母连接成单词
    • 把单词连成句子(用空格隔开)
    所以你的代码看起来像

    StringJoiner sentence = new StringJoiner(" ");    // decoded words should be 
                                                      // separated with single space
    for (String section : code.split("   ")){ 
        StringBuilder word = new StringBuilder();
        for(String morse : section.split(" ")){
            word.append(MorseCode.get(morse));
        }
        sentence.add(word.toString());
    }
    
    String result = sentence.toString();
    

    如果您不喜欢在每次迭代中(针对每个单词)重新创建StringBuilder,您可以在循环之前创建一个,并在每次迭代开始时使用
    setLength(0)

    重置它。您的问题不清楚。您面临什么问题?这不是一个完整的代码示例,它有任何问题,我不知道在Java中拆分是如何工作的。但是,在输入
    code
    中可能有三个空格在后面,这会给您带来问题。请尝试使用调试器,信息技术helps@DavidWalschots这可能是邮件空格的编码方式。也许一个正则表达式可以处理两个或多个连续的空格字符,并将其转换为单个
    \\s
    字符,这将是一个很好的解决问题的方法。@Bryan您在说哪个问题?我不知道你的评论和我的回答有什么关系,我认为这是解决OP问题的好办法。我道歉。你的解决方案是可靠的,我的回答含糊不清。我指的是你答案第二段的第一句话,关于向OP建议如何处理空字符的编码。@Bryan我相信OP的摩尔斯电码将原始消息中的空格表示为三个连续的空格;如果他用一个空格替换2+个连续空格,他就失去了空格,只输出
    HEYJUDE
    。然而,我认为在莫尔斯电码中,空格通常被编码为斜杠,因此如果他的莫尔斯电码处理斜杠,那么用“/”替换三个连续空格可能比我的解决方案容易得多。这仍然存在OP试图解决的问题()@Aaron它确实。。。“我稍后会解决这个问题,目前无法在移动设备上解决。”Aaron编辑了答案,现在应该可以解决了。但是Pshemo给的那个要好得多。