【问题标题】:Converting Morse Code to English Dictionary Words将摩尔斯电码转换为英语词典单词
【发布时间】:2019-03-16 00:18:49
【问题描述】:

我正在尝试解决给定一串摩尔斯电码字符在字典中找到有意义的单词的问题

例如

这个输入字符串“..-.----..-.-.........-.--”应该翻译成“狐狸懒惰”,可能有多种其他翻译,但是这是一种可能的解决方案,因为这两个词出现在英语词典中。

我写了 2 个函数,TranslateMorse 和 SegmentString。 SegmentString 拆分一个英文字符串并在字典中查找所有有意义的单词。例如,如果输入是“foxlazy”,该函数可以找到“fox”和“lazy”是字典中存在的 2 个有意义的词。

TranslateMorse 实际上应该将莫尔斯电码输入“..-.----..-.-....---..-.--”转换为“foxlazy”,以便 SegmentString 给出结果输出,但棘手的部分是摩尔斯电码翻译不是直截了当的,它给了我很多翻译。

我该如何解决这个问题?

import java.util.*;

public class MorseCode {
    String TranslateMorse(String input, Map<String, String> morse) {
        // "-.-..-.--..--...-....---"
        if (morse.containsKey(input))
            return morse.get(input);
        int len = input.length();
        for (int i = 1; i < len; i++) {
            String prefix = input.substring(0, i);
            if (morse.containsKey(prefix)) {
                String suffix = input.substring(i, len);
                String segSuffix = SegmentString(suffix, morse);
                if (segSuffix != null) {
                    return morse.get(prefix) + segSuffix;
                }
            }
        }
        return null;
    }

    String SegmentString(String input, Set<String> dict) {
        if (dict.contains(input))
            return input;
        int len = input.length();
        for (int i = 1; i < len; i++) {
            String prefix = input.substring(0, i);
            if (dict.contains(prefix)) {
                String suffix = input.substring(i, len);
                String segSuffix = SegmentString(suffix, dict);
                if (segSuffix != null) {
                    return prefix + " " + segSuffix;
                }
            }
        }
        return null;
    }

    // Driver method
    public static void main(String args[]) {
        Map<String, String> morse = new HashMap<>();
        morse.put(".-", "a");
        morse.put("-...", "b");
        morse.put("-.-.", "c");
        morse.put("-..", "d");
        morse.put(".", "e");
        morse.put("..-.", "f");
        morse.put("--.-", "g");
        morse.put("....", "h");
        morse.put("..", "i");
        morse.put(".---", "j");
        morse.put("-.-", "k");
        morse.put(".-..", "l");
        morse.put("--", "m");
        morse.put("-.", "n");
        morse.put("---", "o");
        morse.put(".--.", "p");
        morse.put("--.-", "q");
        morse.put(".-.", "r");
        morse.put("...", "s");
        morse.put("-", "t");
        morse.put("..-", "u");
        morse.put("...-", "v");
        morse.put(".--", "w");
        morse.put("-..-", "x");
        morse.put("-.--", "y");
        morse.put("--..", "z");

        Set<String> dict = new HashSet<>();
        dict.add("apple");
        dict.add("honey");
        dict.add("fox");
        dict.add("quick");
        dict.add("jumped");
        dict.add("bill");
        dict.add("jam");
        dict.add("holy");
        dict.add("mega");
        dict.add("lazy");
        // fox lazy
        String input = "..-.----..-.-...---..-.--";
        MorseCode m = new MorseCode();
        String alpha = m.TranslateMorse(input, morse);
        System.out.println(alpha);
        System.out.println(m.SegmentString(alpha, dict));
    }
}

【问题讨论】:

    标签: java recursion morse-code


    【解决方案1】:

    我假设这个问题的重点是在莫尔斯点击流中没有字母,也没有单词,分隔符(空格),这是分析的一部分。我在您的代码中看到的关键问题是:

    • 您假设您将获得一个单一的答案,这反映在您选择的数据类型中,而实际上您将获得多个需要过滤的答案。

      李>
    • 您的 TranslateMorse() 方法在应该递归调用自身时调用 SegmentString()

    下面是我对解决这两个问题的代码的修改:

    import java.util.*;
    
    public class MorseCode {
    
        List<String> TranslateMorse(String input, Map<String, String> dictionary) {
            List<String> strings = new ArrayList<String>();
    
            if (dictionary.containsKey(input)) {
                strings.add(dictionary.get(input));
            }
    
            int length = input.length();
    
            for (int i = 1; i < length; i++) {
                String prefix = input.substring(0, i);
    
                if (dictionary.containsKey(prefix)) {
                    String suffix = input.substring(i, length);
                    List<String> translations = TranslateMorse(suffix, dictionary);
    
                    if (! translations.isEmpty()) {
                        String letter = dictionary.get(prefix);
    
                        for (String translation : translations) {
                            strings.add(letter + translation);
                        }
                    }
                }
            }
    
            return strings;
        }
    
        List<String> SegmentString(String input, Set<String> wordList) {
            List<String> strings = new ArrayList<String>();
    
            if (wordList.contains(input))
                strings.add(input);
    
            int length = input.length();
    
            for (int i = 1; i < length; i++) {
                String prefix = input.substring(0, i);
    
                if (wordList.contains(prefix)) {
                    String suffix = input.substring(i, length);
                    List<String> expansions = SegmentString(suffix, wordList);
    
                    if (! expansions.isEmpty()) {
                        for (String expansion : expansions) {
                            strings.add(prefix + " " + expansion);
                        }
                    }
                }
            }
    
            return strings;
        }
    
        public static void main(String args[]) {
            Map<String, String> morse = new HashMap<>();
    
            morse.put(".-", "a");
            morse.put("-...", "b");
            morse.put("-.-.", "c");
            morse.put("-..", "d");
            morse.put(".", "e");
            morse.put("..-.", "f");
            morse.put("--.-", "g");
            morse.put("....", "h");
            morse.put("..", "i");
            morse.put(".---", "j");
            morse.put("-.-", "k");
            morse.put(".-..", "l");
            morse.put("--", "m");
            morse.put("-.", "n");
            morse.put("---", "o");
            morse.put(".--.", "p");
            morse.put("--.-", "q");
            morse.put(".-.", "r");
            morse.put("...", "s");
            morse.put("-", "t");
            morse.put("..-", "u");
            morse.put("...-", "v");
            morse.put(".--", "w");
            morse.put("-..-", "x");
            morse.put("-.--", "y");
            morse.put("--..", "z");
    
            Set<String> english = new HashSet<>();
    
            english.add("apple");
            english.add("honey");
            english.add("fox");
            english.add("quick");
            english.add("jumped");
            english.add("bill");
            english.add("jam");
            english.add("holy");
            english.add("mega");
            english.add("lazy");
    
            String input = "..-.----..-.-...---..-.--"; // fox lazy
            MorseCode decoder = new MorseCode();
            List<String> decodings = decoder.TranslateMorse(input, morse);
    
            for (String decoding : decodings) {
                List<String> phrases = decoder.SegmentString(decoding, english);
    
                for (String phrase : phrases) {
                    System.out.println(input + " -> " + decoding + " -> " + phrase);
                }
            }
        }
    }
    

    用法

    > java MorseCode
    ..-.----..-.-...---..-.-- -> foxlazy -> fox lazy
    >
    

    这不是一个快速的程序——在这个例子中它需要大约 10 秒,因为它必须将所有可能的 dit 和 dahs 解释过滤成摩尔斯电码符号,然后通过英语单词列表过滤这些。

    【讨论】:

    • 非常感谢@cdlane 我注意到我在翻译莫尔斯语中调用 SegmentString 的错误,但即使在修复了排列和组合太高的问题之后,尤其是没有分隔符(这不是理想的情况下,即使在现实世界中,摩尔斯电码也总是有一个字符分隔符。单词分隔符是可选的)。再次感谢更正的代码。就像你提到的,这需要很长时间。我相信函数的复杂性是指数级的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-04
    • 1970-01-01
    • 1970-01-01
    • 2020-02-11
    • 2010-12-23
    • 1970-01-01
    相关资源
    最近更新 更多