Python,找出给定摩尔斯电码中所有可能的字母组合

Python, find all the possible letter combinations in given morse code

我必须在给定的摩尔斯电码中找到所有可能的字母组合。 解码单词的长度可以是最多10个字母。包含字母和莫尔斯电码的给定文件如下所示:

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   --..

给出的摩尔斯电码是这样的:

morse = '-.----.-.-...----.-.-.-.----.-'

我的代码如下所示:

def morse_file_to_dict(filename):
    with open(filename) as file:
        return dict(line.strip().split() for line in file)


def word_to_morse(s, my_dict):
    return ''.join([my_dict[w] for w in s])


def adding_to_set(given_morse, my_set, my_dict, word='', start=0):
    for char in my_dict:
        if my_dict[char] == given_morse[start:start + len(my_dict[char])] and len(word) < 10:
            start = start + len(my_dict[char])
            word = word + char
            adding_to_set(given_morse, my_set, my_dict, word, start)
            if word_to_morse(word, my_dict) == given_morse:
                my_set.add(word)


words = set()
morse = '-.----.-.-...----.-.-.-.----.-'
pairs = morse_file_to_dict('morse_alphabet.txt')
adding_to_set(morse, words, pairs)
print(len(words))
print(words)

我的输出是:

5
{'KMCBMQRKMK', 'KMCBMGKRMQ', 'KMCBMGCKMK', 'KMNCEJCCMQ', 'KMCDAMCCMQ'}

但是,答案应该是:10571 个单词,而不是 5

我应该改变什么才能获得所有这些? 谢谢你的时间和回答!

c++解决方案:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

char buffer[26];
int l=0;
char *Morse[26];
//initializing Morse Code array
void initMorse(){
Morse[0] = "._" ;            
Morse[1] = "_...";            
Morse[2] = "_._." ;            
Morse[3] = "_.." ;            
Morse[4] = "." ;   //E         
Morse[5] = ".._." ;            
Morse[6] = "__." ;            
Morse[7] = "...." ;  //H          
Morse[8] = ".." ;       //I     
Morse[9] = ".___" ;   //J         
Morse[10] = "_._" ;  //K            
Morse[11] = "._.." ;            
Morse[12] = "__" ;   //M         
Morse[13] = "_." ;            
Morse[14] = "___" ;     //O       
Morse[15] = ".__." ;  //P            
Morse[16] = "__._" ;            
Morse[17] = "._." ;   //R         
Morse[18] = "..." ;            
Morse[19] = "_" ;            
Morse[20] = ".._" ;            
Morse[21] = "..._" ;  //V          
Morse[22] = ".__" ;            
Morse[23] = "_.._" ;            
Morse[24] = "_.__" ;            
Morse[25] = "__.." ; //Z
}
int solution(char *s,int strt,char **Morse,int len){
    int i,j,noMatch=0,k,prev,tem;
    int mlen;
    if(strt!=len)
    for(i=0;i<26;i++){
    mlen=strlen(Morse[i]);
     if(strt+mlen<=len){
        for(j=strt,k=0;j<strt+mlen&&k<mlen;j++,k++){
            if(Morse[i][k]==s[j])
                continue;
            else {
                noMatch=1;
                break;
            }
        }
    }
    else{
        continue;   
    }
    if(noMatch==0){
         //print pattern when complete string matched
         if(strt+mlen==len){
          buffer[l]=i+65;
             printf("%s\n",buffer);
             buffer[l]=0;
        }
        else{
            noMatch=0;  
            buffer[l]=i+65;
            l++;
            solution(s,strt+mlen,Morse,len);
            l--;                 // while backtracking 
            buffer[l]=0;      //  clearing buffer just upto the previous location 
        }
    }
    else{
        noMatch=0;
    }
}
else{
    buffer[l]=0;
}
return 1;
}

int main() {

char s[100];
printf("Enter the input string of Morse code:\n");
scanf("%s",s);
initMorse();
printf("Possible translations are:\n");
solution(s,0,Morse,strlen(s));
for
return 0;
}

我建议使用递归和字典将莫尔斯电码映射到字母(而不是字母到莫尔斯电码):

morseFile="""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   --.."""

morse = {code:letter for line in morseFile.split("\n") for letter,code in [line.split()]}

可以将函数构建为生成器,以避免将所有可能性存储在一个大列表中:

def decode(coded,maxLen=10):
    if not maxLen: return
    for size in range(1,min(4,len(coded))+1):
        code = coded[:size]
        if code not in morse: continue
        remaining = coded[size:]
        if not remaining: yield morse[code]
        for rest in decode(remaining,maxLen-1):
            yield morse[code] + rest

输出:

print(sum(1 for _ in decode("-.----.-.-...----.-.-.-.----.-")))

10571

for string in decode("-.----.-.-...----.-.-.-.----.-"):
    if len(string)<9: print(string)

YQLWGCYQ
YQLWQRYQ
YQLJNCYQ
YQLJKRYQ
YQLJCNYQ
YQLJCKWQ
YQLJCKJK
YQLJCCMQ
YQLJCCOK

这是一个可行的解决方案。我对评论和答案中的代码和建议进行了更改。 (翻译的莫尔斯电码也不一样)

    def word_to_morse(s, my_dict):
        return ''.join([my_dict[w] for w in s])

    def adding_to_set(given_morse, my_set, my_dict, word='', start=0):
        for char in my_dict:
            if my_dict[char] == given_morse[start:start + len(my_dict[char])] and len(word) < 10:
                new_start = start + len(my_dict[char])
                new_word = word + char
                adding_to_set(given_morse, my_set, my_dict, new_word, new_start)
                if word_to_morse(new_word, my_dict) == given_morse:
                    my_set.add(new_word)
    words = set()

    # the morse code I want to decrypt
    morse = '.-.--...-....-.'

    # adding morse alphabet here
    pairs={'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': '--..',

     
    }
    adding_to_set(morse, words, pairs)
    print(len(words))
    print(words)