首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无空格Morse码的翻译

无空格Morse码的翻译
EN

Stack Overflow用户
提问于 2011-12-01 22:21:09
回答 2查看 17.9K关注 0票数 5

我有一些莫尔斯密码,在字母之间失去了空格,我的挑战是找出信息是什么。到目前为止,我已经有点迷失了,因为可能有大量的组合。

这是我收到的所有信息。

输出将是英语-..-...-...-...-..-.-.-.-.-..-.-.-.-.-.-.-.-.-.-..-...-.

  • The

  • ,这里总是有一个有意义的翻译,例如消息
  • 消息应该不再是从一个较长的流中提取70条 morse代码,所以有可能第一组或最后一组被切断,因此没有有效的翻译

有人有聪明的解决方案吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-12-04 13:07:18

这并不是一个容易的问题,因为正如鲁哈克所指出的,对于给定的信息,有许多可行的句子。例如,‘杰克和吉尔上山’的编码和‘杰克和吉尔走凿’相同的编码。由于这两个句子都是语法句子,而且每个单词都是常见的,因此在不深入研究自然语言处理的情况下,如何选择一个或另一个(或40141055989476564163599不同的英语单词序列中的任何一个与这条信息具有相同编码的不同序列)并不明显。

无论如何,这里有一个动态规划的解决方案来解决寻找最短句子的问题(如果有平数的话,用最少的字符)。它还可以计算与给定消息具有相同编码的句子总数。它需要一个文件中的英文单词字典。

接下来的增强应该更好地衡量句子的可能性:也许是单词频率,莫尔斯中的假阳性率(例如,"I“是一个常见的单词,但它经常出现在摩尔斯代码序列的其他序列中)。棘手的部分将是制定一个好的分数函数,可以表达的方式,它可以计算,使用动态规划。

代码语言:javascript
复制
MORSE = dict(zip('ABCDEFGHIJKLMNOPQRSTUVWXYZ', [
    '.-', '-...', '-.-.', '-..', '.', '..-.', '--.', '....',
    '..', '.---', '-.-', '.-..', '--', '-.', '---', '.--.',
    '--.-', '.-.', '...', '-', '..-', '...-', '.--', '-..-',
    '-.--', '--..'
]))

# Read a file containing A-Z only English words, one per line.
WORDS = set(word.strip().upper() for word in open('dict.en').readlines())
# A set of all possible prefixes of English words.
PREFIXES = set(word[:j+1] for word in WORDS for j in xrange(len(word)))

def translate(msg, c_sep=' ', w_sep=' / '):
    """Turn a message (all-caps space-separated words) into morse code."""
    return w_sep.join(c_sep.join(MORSE[c] for c in word)
                      for word in msg.split(' '))

def encode(msg):
    """Turn a message into timing-less morse code."""
    return translate(msg, '', '')

def c_trans(morse):
    """Construct a map of char transitions.

    The return value is a dict, mapping indexes into the morse code stream
    to a dict of possible characters at that location to where they would go
    in the stream. Transitions that lead to dead-ends are omitted.
    """
    result = [{} for i in xrange(len(morse))]
    for i_ in xrange(len(morse)):
        i = len(morse) - i_ - 1
        for c, m in MORSE.iteritems():
            if i + len(m) < len(morse) and not result[i + len(m)]:
                continue
            if morse[i:i+len(m)] != m: continue
            result[i][c] = i + len(m)
    return result

def find_words(ctr, i, prefix=''):
    """Find all legal words starting from position i.

    We generate all possible words starting from position i in the
    morse code stream, assuming we already have the given prefix.
    ctr is a char transition dict, as produced by c_trans.
    """
    if prefix in WORDS:
        yield prefix, i
    if i == len(ctr): return
    for c, j in ctr[i].iteritems():
        if prefix + c in PREFIXES:
            for w, j2 in find_words(ctr, j, prefix + c):
                yield w, j2

def w_trans(ctr):
    """Like c_trans, but produce a word transition map."""
    result = [{} for i in xrange(len(ctr))]
    for i_ in xrange(len(ctr)):
        i = len(ctr) - i_ - 1
        for w, j in find_words(ctr, i):
            if j < len(result) and not result[j]:
                continue
            result[i][w] = j
    return result

def shortest_sentence(wt):
    """Given a word transition map, find the shortest possible sentence.

    We find the sentence that uses the entire morse code stream, and has
    the fewest number of words. If there are multiple sentences that
    satisfy this, we return the one that uses the smallest number of
    characters.
    """
    result = [-1 for _ in xrange(len(wt))] + [0]
    words = [None] * len(wt)
    for i_ in xrange(len(wt)):
        i = len(wt) - i_ - 1
        for w, j in wt[i].iteritems():
            if result[j] == -1: continue
            if result[i] == -1 or result[j] + 1 + len(w) / 30.0 < result[i]:
                result[i] = result[j] + 1 + len(w) / 30.0
                words[i] = w
    i = 0
    result = []
    while i < len(wt):
        result.append(words[i])
        i = wt[i][words[i]]
    return result

def sentence_count(wt):
    result = [0] * len(wt) + [1]
    for i_ in xrange(len(wt)):
        i = len(wt) - i_ - 1
        for j in wt[i].itervalues():
            result[i] += result[j]
    return result[0]

msg = 'JACK AND JILL WENT UP THE HILL'
print sentence_count(w_trans(c_trans(encode(msg))))
print shortest_sentence(w_trans(c_trans(encode(msg))))
票数 8
EN

Stack Overflow用户

发布于 2011-12-01 23:16:24

保持三样东西:到目前为止的单词列表,到目前为止的单词W,以及当前符号C。

  • S应该只是好词,例如。
  • W应该是一个单词的有效前缀,例如。
  • C应该是某个字母的有效前缀,例如。“.-”

现在,给出一个新的符号,比方说'-',我们用它扩展C(在这种情况下,我们得到‘.-’)。如果C是一个完整的字母(在本例中是' W '),我们可以选择将它添加到W中,或者通过添加更多的符号来继续扩展该字母。如果我们扩展W,我们可以选择将它添加到S(如果它是一个有效的单词),或者继续扩展它。

这是一种搜索,但大多数路径都会很快终止(只要W不是任何单词的有效前缀,就可以停止,而且只要C不是任何字母的前缀,就可以停止)。

为了提高效率,您可以使用动态编程来避免冗余工作,并使用尝试有效地测试前缀。

代码是什么样子的?省略函数“is_word”(测试字符串是否为英语单词)和“is_word_prefix”函数(测试字符串是否为任何有效单词的开头),如下所示:

代码语言:javascript
复制
morse = {
    '.-': 'A',
    '-...': 'B',
    etc.
}

def is_morse_prefix(C):
    return any(k.startswith(C) for k in morse)

def break_words(input, S, W, C):
    while True:
        if not input:
            if W == C == '':
                yield S
            return
        i, input = input[0], input[1:]
        C += i
        if not is_morse_prefix(C):
            return
        ch = morse.get(C, None)
        if ch is None or not is_word_prefix(W + ch):
            continue
        for result in break_words(input, S, W + ch, ''):
            yield result
        if is_word(W + ch):
            for result in break_words(input, S + ' ' + W + ch, '', ''):
                yield result

for S in break_words('....--', [], '', ''):
    print S
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8349136

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档