不含空格的摩尔斯电码是否可以唯一识别?


54

所有摩尔斯电码字符串都可以唯一识别吗?没有空格

......-...-..---.-----.-..-..-..

可能是,Hello World但第一个字母可能是5-实际上,它看起来不太可能任意点和破折号序列都具有唯一的翻译。

一个人可能会使用Kraft不等式,但这仅适用于前缀代码

带空格的摩尔斯电码是前缀代码,在其中始终可以唯一地解码消息。一旦我们删除了空格,这将不再成立。


在我是对的情况下,不能完全解码所有摩尔斯电码消息的情况,有没有办法列出所有可能的消息?这是我在codegolf.SE上发现的一些相关练习


7
您似乎已经回答了自己的问题?
拉斐尔

7
“莫尔斯码不带空格”不是莫尔斯码。空格是规范的一部分,因为没有它们,代码将无法识别。
斯蒂芬·肯尼迪

1
@StephenKennedy那已经是问题了。你看完了吗?
拉斐尔

3
Perl脚本列出可能的代码消息。没有意识到这是一个纯粹的理论社区。:)
Squeezy 2014年

1
您真的确定接受的答案完全可以作为答案,甚至可以暗示任何内容吗?我的意思是很明显ET = A ...证明了斯皮尔伯格是对的:ET是外星人。
babou 2014年

Answers:


91

以下都是合理的消息,但含义完全不同:

SOS HELP      = ...---...  .... . .-.. .--.        => ...---.........-...--.
I AM HIS DATE = ..  .- --  .... .. ...  -.. .- - . => ...---.........-...--.

6
可爱,但是已经确定没有空间的莫尔斯模棱两可,所以我真的认为这比评论更有价值。
David Richerby 2014年

37
OP似乎在询问是否可以将一系列不带空格的点和点解释为两个“真实”消息,而不是TE的任意序列。第一个SOS!救命!由两个感叹词组成,第二个“ 我是他的约会”是一个语法合理的英语句子,因此两者都是有效的信息。这通过提供一个示例简洁地回答了这个问题。
CJ丹尼斯

2
@CJDennis这个问题根本没有说明。它询问是否存在莫尔斯字符串可以唯一地解密,以及是否存在一种方法来列出所有编码为给定序列(如果是点和破折号)的字符串。它对于必须具有英语含义的字符串一无所知。
David Richerby 2014年

2
既有一个具体的(反)例子,又有一个研究问题的一般方法,两者都与良好的答案有关。参见例如lakatos的证据/反驳
vzn 2014年

3
“说什么,少尉?” I AM HIS DATE“所以,阿米莉亚决定与老的Noonan私奔,我们应该把它留给自己。”
dotancohen 2014年

36

引用David Richerby的评论:

由于⋅表示E和-表示T,没有空格任何莫尔斯消息可以被解释为在一个字符串{E,T}

此外,由于A,I,M和N由两个摩尔斯字符(分别为⋅-,⋅⋅,-,-⋅)的四个可能的组合表示,所以任何不带空格的消息也可以解释为字符串 。请注意,对于任何长度大于1的摩尔斯电文,这与David的解释是不同的。因此,唯一具有唯一解释的消息是长度为1的消息(如果算作一条消息,我想为0),即⋅表示E,而-表示T。{A,I,M,N}{E,T}?

这是一些JavaScript,可以告诉您对.and 字符串的所有可能解释-。长度最大为22的字符串在不到一秒钟的时间内就会运行,但是任何超出此长度的字符串都会变得非常慢-例如,我不会尝试使用它来解码HELLO WORLD。您可以在浏览器中弹出一个JavaScript控制台,将其粘贴,然后调用,例如decode('......-...-..---')。(在此示例中,条目#2446是预期的字符串“ HELLO”。)

var decode = function(code) {
  var cache = {
    '0': ['']
  };
  for(var start = 0;start < code.length;start++) {
    for(var len = 1;len < 6;len++) {
      if(start + len > code.length) continue;
      if(!cache[start + len]) cache[start + len] = [];
      var curCode = code.slice(start, start + len);
      if(dict[curCode]) {
        for(var i_start = 0;i_start < cache[start].length;i_start++) {
          cache[start + len].push(cache[start][i_start] + dict[curCode]);
        }
      }
    }
  }
  return cache[code.length];
};

var dict = {
  '.-': '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'
};

将其仅修剪为实际单词字符串的代码要长一些,因此我将其放在此处。它在node.js下运行,并期待在的文件/usr/share/dict/words-2500。我正在使用的字典可以在这里找到。它不是幼稚的-它会修剪,因此在较大的输入上运行速度快得多。

该词典由我在互联网上某个地方找到的前2500个单词列表组成,减去了一些我认为不是单词的1、2和3个字母的组合。该算法对有太多短单词可供选择非常敏感,并且如果您允许将每个字母都作为一个单词(如果我看着您/usr/share/dict/words),则会大大降低速度。

该算法以单词数量为基础进行排序,因此“有趣的”单词将有望排在最前面。此方法适用于HELLO WORLD,运行时间不到一秒,可将期望的词组作为第一匹配返回。从中我还了解到DATA SCIENTIST(我尝试过的唯一其他短语)莫尔斯电码与相同NEW REAL INDIA

编辑:我搜索了一些有趣的几分钟。单词SPACESSWITCH是词形图。到目前为止,它们是我发现的最长的单字对。


3
您刚刚发明了词形文字吗?我非常喜欢它,但是网络搜索提供了指向该站点的单个链接。
BmyGuest 2014年

我还可以自由地将这个有趣的问题变成Puzzling.SE上的一个公开挑战,并参考此处的一些帖子。
BmyGuest 2014年

@BmyGuest是的,这是一个完全虚构的词。不过,我有点喜欢。
亚伦·迪

17

足以观察到某些短字母组合给出了模棱两可的解码。一个模糊的序列就足够了,但是我可以看到以下内容:

ATE ~ P
EA ~ IT
MO ~ OM

正如David Richerby评价注意到,任何字母相当于到Es和TS的串,这使得莫尔斯电码暧昧为编码的信任意序列的一种方式; 以上组合表明,即使是英文中的合理字母组合(例如MEATMITT),也是如此。也许一个有趣的编码练习是找到所有五个或更少字母的字符串,这些字符串可能会被误认为其他东西,限制为实际上可以在英语文本中找到的字母组合(使用一个或多个单词),并按等价类分组。

使用您的原始示例,恰好是

HELLO WORLD ~ HAS TEAM NO MAID TOE

尽管即使只是部分消息,右侧也许也不现实,但它肯定是一连串的英语单词,并且可以在不到15分钟的时间内找到它,而无需计算机的帮助。这可以作为证据,证明许多英语短语可能会被误解为英语单词的其他(可能是无意义的)序列。


MT vs TM是一个非常简短的例子。
拉斐尔

2
@Raphael MT == TM == O所有三个都是相同的序列。这使得翻译非常困难。
Red_Shadow 2014年

10

摩尔斯电码实际上是三元代码,而不是二进制代码,因此必须有空格。如果没有空格,则会导致很多歧义,不是整个消息,而是单个字母。

例如,两个点是一个I,但是三个点是一个S。如果您正在转录并且听到两个点,您是立即写“ I”还是等到听到另一个点(或破折号)?

答案是每个值都用空格分隔,因此将它们分组在一起。当操作员在莫尔斯电文中键入消息时,他们会在每个字母代码序列之后暂停一个与破折号相同长度的停顿,以指示序列的结尾。

即使您编写了一个AI程序一次查看一个完整的句子并弄清楚消息的逻辑解释是什么,仍然会有许多轻微的歧义和拼写错误,


2
您的最后一句话似乎已被截断。
David Richerby 2014年

2
@DavidRicherby是的,这是因为我试图使用莫尔斯电码在无空格的情况下发布帖子。
泰勒·德登

4

一些未在其他(好的)答案中涵盖的笔记,但通常不会研究先验知识,也不会引用任何东西(对我而言,是计算机科学的固有组成部分)。

  • CS的一般理论属于文本分割和“单词拆分” /“歧义消除” 类别,尽管那里的理论有些不同,它涉及将符号序列拆分为单词(带有可变字母)等,其中符号是单位。在这里,字符串被拆分为字母,字母的长度可变,但是该理论是相似的,尽管不完全是1-1。例如,将句子翻译成单词,可变单词字母长度和句子翻译成单词,可变单词/字母长度之间的映射。

  • 正如其他人指出的那样,可以凭经验进行研究。然后有人从一个角度做到了这一点(有多种研究方法),然后将结果“发布”在网页上,该网页具有很大的目录/结果表。

    我发现25,787个莫尔斯电码不明确。它由10,330个不同的莫尔斯弦组成。频率最高的歧义摩尔斯词有13个可能的施主词。结果根据共享相同摩尔斯表示的单词出现频率在下表中分组。

  • 哇,“上下文很重要” ... 3年之前stackoverflow上的一个几乎相同的问题“不带空格的莫尔斯电码翻译”目前有0票。


2

一般而言,可能会有指数级的解码,但是如果您确实想要,可以将它们全部列出。您也可以以简洁的方式列出它们,即为所有它们给出简洁的表示。由于这只不过是编程练习,所以我挑战您自己去做。

就是说,存在歧义的事实并不排除解密消息或至少消息的大部分的能力。假设使用摩尔斯电码表示的文本具有概率模型(为了确定性),我们可以假设它是英语,并使用英语的统计属性,尽管有一些本地歧义是不可避免的,但实际上可以对消息进行解码。原因是大多数解码对应于无意义的明文。这样做的方法是从上一段扩展动态编程算法,以估计每个解码的可能性,然后选择最大似然解码。随着消息变得更长,此方法更有可能成功。


不将Viterbi算法做类似于你所描述的东西吗?量化解码数量的指数增长,是否是此处合适的问题,或cstheory.SE?
约翰·曼格

1
没错,这个想法是使用动态编程。估计指数增长可能比cstheory更适合这里。
Yuval Filmus 2014年

实际上,这与语音处理中识别单词的过程非常相似。结果就是所谓的词格,它是所有可能与所分析的声音序列匹配的词序列的简明表示。
babou 2014年

1

如何定义/识别/生成所有可能解码的语言。

显然,没有空格,莫尔斯电码不再是唯一可解密的。

但是有可能以压缩形式给出所有可能的解码方式。这实际上类似于语音处理中的处理:从独特的声音流(或音素流)中,您必须找到可以按单词序列分解的所有方式。用于执行此操作的算法会产生所谓的单词晶格。您可以在“词汇歧义”部分找到一个示例此答案

对于二进制摩尔斯电码(没有空格),您只有点和破折号,但是问题是相同的。

获得所有翻译的方式如下。

T可识别摩尔斯电码特里。识别出代码后,将输出相应的字母/数字,并且(不确定)返回到trie根的空过渡。但是同时,代码字可能会继续(不确定)地变成一个更长的代码字。

wnWn+10nL={w}=L(W)T(L)T(L)

TWTW

细节很容易解决。但是,请问您是否需要更多。


0

求解器的一些伪代码将给出所有可能的解释。这是基于一些快速的想法,因此欢迎您提供其他意见。方法接受两个输入,一个是到目前为止翻译的文本,第二个是莫尔斯电码。

MorseSolver (string textSoFar, string codeRemaining)
{
    if(codeRemaining length == 0) output textSoFar
    else
    {
        codeLength = length of code remaining
        read 1 through (min of 5 or codeLength) characters from codeRemaining
        for each set of characters
        {
            call an IsMorseCode method that checks if the characters 
              input are valid morse code
            if they are valid add the translated character to textSoFar 
              and remove the characters from codeRemaining, then call 
              the MorseSolver again with the new strings)
        }

}

这将输出字母和数字的所有可能组合,并且“单词”之间没有任何空格。如果您想证明歧义,那一定可以做到。如果您想发出一些有意义的消息,请尝试查找旨在将主题标签转换为可读语言的代码。

使用上面的代码,我用C#编写了一个完成上面的程序。我停止了上述字符串转换为问候世界的2200万种可能性。摩尔斯电码等效于“ Hello”的结果为20,569。我也没有包括数字。如果我允许他们,那会更高。


这样的算法的输出将证明任何单个字符串都是模棱两可的,但并不能证明所有字符串都是模棱两可的。
David Richerby 2014年

@DavidRicherby所有长度> 1的字符串都不明确。在此页面的其他地方已证明这一点。我试图回答问题的第二部分,并提供一种从字符串中推断所有可能的解决方案的方法。
Red_Shadow 2014年

出于好奇,您会分享您的C#程序吗?我的Perl版本附带了19796种可能的“ HELLO”等效解决方案。我很可能忘记了输出某些案件……
Squeezy 2014年

1
真正的源代码在这里无关紧要;请将其发布到其他位置(pastebin,Gist等),并仅链接到该链接。
拉斐尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.