C语言 C 中的摩尔斯电码转换器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28045172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 11:42:09  来源:igfitidea点击:

Morse Code Converter in C

cencoderdecoder

提问by HerlDerp

Yes its homework We were suppose to have char 2D array holding character with size limit of 255 char char string[100][255];

是的,它的作业我们假设有一个字符 2D 数组,其中包含大小限制为 255 个字符的字符 char string[100][255];

Program neede: change the input morse code by a user to alphabet/English letter (Capital Letters)

程序需要:将用户输入的莫尔斯电码改为字母/英文字母(Capital Letters)

Sample Input

样本输入

2

 .... . .-.. .-.. --- / .-- --- .-. .-.. -..

 .--- --- -.- .

Sample OutPut

样品输出

  • Case#1:

    HELLO WORLD
    
  • Case#2:

    JOKE
    
  • 情况1:

    HELLO WORLD
    
  • 案例#2:

    JOKE
    

My only idea is to have the first characters of a word that is inputed by the user.. to be.. checked if its '.' or '-' then scrupulously and manually assigning.. the nested if(string[i][c]=='.')and the last if on each nested would be if(string[i][c]==' ')then that prints out the letter "E" example

我唯一的想法是让用户输入的单词的第一个字符......要......检查它的“。” 或 '-' 然后小心翼翼地手动分配......if(string[i][c]=='.')每个嵌套的嵌套和最后一个 if 将if(string[i][c]==' ')打印出字母“E”示例

if(string[i][c]=='.') {
    isspace(string[i][c+1])
    printf("E");
}

Now my question is.. is there any easier way for this problem? where i don't have to type the same '-' and '.' if statement.. and stuff? and have my mind explode? because I lose track of corresponding the next char with if or case statements?

现在我的问题是..有没有更简单的方法来解决这个问题?我不必输入相同的“-”和“.” 如果声明.. 和东西?我的脑子爆炸了吗?因为我失去了与 if 或 case 语句对应的下一个字符的跟踪?

回答by M Oehm

You have already discovered that you can branch on each morse signal and that it is tiresome to hard-code all that as if-elsestatements. When you have done so, you will have noted a certain structure with ever deeper nested conditions. You can represent this structure as a tree:

您已经发现您可以在每个莫尔斯信号上进行分支,并且将所有这些硬编码为if-else语句是很烦人的。当您这样做时,您将注意到具有更深嵌套条件的特定结构。您可以将此结构表示为树:

                       *
                   /       \
               E               T
             /   \           /   \
           I       A       N       M
          / \     / \     / \     / \ 
         S   U   R   W   D   K   G   O
        / \ / \ / \ / \ / \ / \ / \ / \ 
        H V F * L * P J B X C Y Z Q * *

That same tree can be found in a (slightly) prettier form in the middle sections of the Wikipedia entry on Morse code. (The asterisks in the lowest row indicate encodings that are not one of the 26 letters of the English alphabet.)

在维基百科莫尔斯电码条目中间部分,可以以(稍微)更漂亮的形式找到同一棵树。(最下面一行中的星号表示不是英文字母表的 26 个字母之一的编码。)

You start at the top. Branch left on a dit, branch right on a dah and read the value when you are done.

你从顶部开始。在 dit 上向左分支,在 dah 上向右分支,完成后读取值。

There are many ways to implement trees. In this case, the tree's branches are all of the same depth, at least if we consider the asterisks, too. You can represent the tree as a linear array by indexing the nodes row-wise. When toe top node is 1, you get:

有很多方法可以实现树。在这种情况下,树的分支都具有相同的深度,至少如果我们考虑星号也是如此。您可以通过按行索引节点来将树表示为线性数组。当脚趾顶部节点为 1 时,您会得到:

                       1
                   /       \
               2               3
             /   \           /   \
           4       5       6       7
          / \     / \     / \     / \ 
         8   9  10  11  12  13  14  15
        / \ / \ / \ / \ / \ / \ / \ / \
       16 ...                     ... 31

You can see that branching left from node nbrings you to node 2*nand branching right brings you to its right neighbour with index 2*n + 1. Build up the index as you go, starting from 1 and then look up your letter in the array:

您可以看到从 node 向左分支n将您带到 node 2*n,向右分支将您带到具有 index 的右侧邻居2*n + 1。随时建立索引,从 1 开始,然后在数组中查找您的字母:

const char *letter = "**ETIANMSURWDKGOHVF?L?PJBXCYZQ??";

(The two asterisks at the front indicate illegal indices.)

(前面的两个星号表示非法索引。)

回答by BLUEPIXY

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

static const char *alpha[] = {
    ".-",   //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
};
static const char *num[] = {
    "-----", //0
    ".----", //1
    "..---", //2
    "...--", //3
    "....-", //4
    ".....", //5
    "-....", //6
    "--...", //7
    "---..", //8
    "----.", //9
};
static const char **table[] = { alpha, num };

typedef enum kind {
    ALPHA, NUM
} Kind;

typedef struct mtree {
    char value;
    struct mtree *dot;
    struct mtree *bar;
} MTree;

MTree *root;

void make_tree(void);
void drop_tree(void);
void encode_out(const char *s);
void decode_out(const char *s);

int main(void){
    make_tree();
    encode_out("HELLO WORLD");
    encode_out("JOKE");
    decode_out(".... . .-.. .-.. --- / .-- --- .-. .-.. -..");
    decode_out(".--- --- -.- .");
    drop_tree();
    return 0;
}

void encode_out(const char *s){
    for(;;++s){
        char ch = *s;
        if(ch == '
#include <stdio.h>
#include <string.h>

typedef struct
{
    char* morse;
    char* ascii;
} morse_table_t;

int main(void) {
    char input[] = ".- -... -.-.";

    morse_table_t table[] = { {".-", "A"},
                              {"-...", "B"},
                              {"-.-.", "C"}
/* TODO: Fill in the rest of the Morse Table Here */
    };

    char* segment;
    int i;
    segment = strtok(input, " ");

    while(segment)
    {
        for(i=0; i<ARRAY_SIZE(table); ++i)
        {
            if (!strcmp(segment, table[i].morse)) puts(table[i].ascii);
        }
        segment = strtok(NULL, " ");
    }

    return 0;
}
') break; if(isalpha(ch)){ ch = toupper(ch); fputs(table[ALPHA][ch - 'A'], stdout);//`-'A'` depend on the sequence of character code } else if(isdigit(ch)) fputs(table[NUM][ch - '0'], stdout); else if(ch == ' ') fputc('/', stdout);//need rest space skip ? else ;//invalid character => ignore fputc(' ', stdout); } fputc('\n', stdout); } static void decode_out_aux(MTree *tree, const char *s){ if(tree == NULL) return; if(*s == '
#include <stdio.h>
#include <string.h>

int main()
{
    /* string array will contain the whole line morse  code */
    char string[256]="";
    /* T is the number of test c ases */
    int T;
    scanf("%d ",&T);
    /* morse array contains all the letters from A to Z in  */
    /* morse code  */
    const char morse[][10]={
        ".-", //morse code of letter A
        "-...", //morse code of letter B
        "-.-." , //morse code of letter C
        "-.." , //morse code of letter D
        "." , //morse code of letter E
        "..-." , //morse code of letter F
        "--." , //morse code of letter G
        "...." , //morse code of letter H
        ".." , //morse code of letter I
        ".---" , //morse code of letter J
        "-.-" , //morse code of letter K
        ".-.." , //morse code of letter L
        "--" , //morse code of letter M
        "-." , //morse code of letter N
        "---" , //morse code of letter O
        ".--." , //morse code of letter P
        "--.-" , //morse code of letter Q
        ".-." , //morse code of letter R
        "..." , //morse code of letter S
        "-" , //morse code of letter T
        "..-" , //morse code of letter U
        "...-" , //morse code of letter V
        ".--" ,  //morse code of letter W
        "-..-" ,  //morse code of letter X
        "-.--" , //morse code of letter Y
        "--.." //morse code of letter Z
    };

    /* i will be used to print the number of test case */
    int i=1;
    /* while loop to do every  case */
    while(T--)
    {
        printf("Case#%d:\n",i);
        /* read the line of more code via f gets */
        fgets(string,sizeof(string),stdin);
        /* strtok is for extracting every word from the  line */
        char *p=strtok(string," ");
        while(p!=NULL)
        {
            /* check if the word is / print space and go to the next  word */
            if(p[0]=='/')
            {
                printf(" ");
                goto next;
            }
            int j=0;
            for(j=0; j<26;j++)
            {
                //check the correspondant string in morse array 
                    if(!strcmp(p,morse[j])) 
                    {
                        /* print the equivalent letter after finding the subscript */
                        /* A=65+0 .... Z=90=65+25 */
                        printf("%c",(j+65));
                    }
            }
next:
            /* fetch the next  word by ignoring space tab newline*/
            p=strtok(NULL,"\t \n");
        }
        printf("\n");
        i++;

    }

    return 0;
}
') fputc(tree->value, stdout); else if(*s == '/') fputc(' ', stdout); else if(*s == '.') decode_out_aux(tree->dot, ++s); else if(*s == '-') decode_out_aux(tree->bar, ++s); } void decode_out(const char *s){ char *p; while(*s){ p = strchr(s, ' '); if(p){ if(p-s != 0){ char code[p-s+1]; memcpy(code, s, p-s); code[p-s]='
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#define MAX 100
#define SIZE 255

int main(){
char string[MAX][SIZE];
char destination[MAX][5];
char *input[37]={".-","-...","-.-.","-..",".","..-.","--.",
                "....","..",".---","-.-",".-..","--","-.",
                "---",".--.","--.-",".-.","...","-","..-",
                "...-",".--","-..-","-.--","--..","-----",
                ".----","..---","...--","....-",".....",
                "-....","--...","---..","----.","/"};
char *output[37]= {"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","0","1","2","3",
                "4","5","6","7","8","9"," "};
int i, c, x, m, j;
printf("Enter the number of Cases:");
scanf("%d", &x);
for(i=0;i<x;i++){
    printf("Case#%d: ", i+1);
        if (i==0){
            gets(string[0]);    }
        gets(string[i]);
}

for(i=0;i<x;i++){
    printf("Case#%d: ",i+1);
    for(c=0,m=0;string[i][c]!='
#include <stdio.h>
#include <string.h>

#define MAX 100
#define SIZE 255

int main(){
    char string[MAX][SIZE] = {
        ".... . .-.. .-.. --- / .-- --- .-. .-.. -..",
        ".--- --- -.- ."
    };
    char destination[MAX][8];
    int x = 2;//number of input
    int i, j, m;
    char *code, *separator = " ";//" " --> " \t\n"
    for(i=0;i<x;++i){
        j = 0;
        for(code = strtok(string[i], separator);
            code != NULL;
            code = strtok(NULL, separator)){
            printf("'%s'\n", code);
            strcpy(destination[j++], code);
        }
        m = j;
        if(strcmp(destination[0], "....")==0)
            puts("yes, It's 'H'.");
    }
    return 0;
}
';c++,m++){ if(isspace(string[i][c])){ m++;} else{ destination[m][c]=string[i][c]; } } for(j=0,m=0;j<37;j++){ if(destination[m]==input[j]){ printf("%d %s \n", i+1, output[j]); m++; } } } return 0; } I might have done something stupid here... ._. i'm just trying though.. does this not work?
'; decode_out_aux(root, code); } s = p + 1; } else { decode_out_aux(root, s); break; } } fputc('\n', stdout); } static void insert_aux(MTree **tree, char ch, const char *s){ if(*tree == NULL) *tree = calloc(1, sizeof(**tree)); if(*s == '
#include<stdio.h>
#include<string.h>
#define MAX 100
#define SIZE 255

int main(){
char string[MAX][SIZE];
char destination[MAX] [MAX][8];
char *input[38]={".-","-...","-.-.","-..",".","..-.","--.",
                "....","..",".---","-.-",".-..","--","-.",
                "---",".--.","--.-",".-.","...","-","..-",
                "...-",".--","-..-","-.--","--..","-----",
                ".----","..---","...--","....-",".....",
                "-....","--...","---..","----.","/"};
char *output[38]={"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","0","1","2","3",
                "4","5","6","7","8","9"," "};
char *code, *separator = " ";
int i, c, x, j;
int m[MAX];
printf("Enter the number of Cases:");
scanf("%d", &x);
getchar();
for(i=0;i<x;i++){
    printf("Case#%d: ", i+1);
        gets(string[i]);
}

for(i=0,j=0;i<x;++i){
    for(code = strtok(string[i], separator);code != NULL;code = strtok(NULL, separator)){
        strcpy(destination[i][j++], code);

    }
    m[i] = j;
}

for(i=0;i<x;i++){
    printf("Case#%d: ", i+1);
    for(j=0;j<m[i];j++){
        for(c=0;c<37;c++){
            if(strcmp(destination[i][j], input[c])==0){
                printf("%s",output[c]);}
        }
    }
    printf("\n");
}
return 0;
}
') (*tree)->value = ch; else if(*s == '.') insert_aux(&(*tree)->dot, ch, ++s); else if(*s == '-') insert_aux(&(*tree)->bar, ch, ++s); } static inline void insert(char ch, const char *s){ if(*s == '.') insert_aux(&root->dot, ch, ++s); else if(*s == '-') insert_aux(&root->bar, ch, ++s); } void make_tree(void){ root = calloc(1, sizeof(*root)); //root->value = '/';//anything int i; for(i = 0; i < 26; ++i) insert('A'+i, table[ALPHA][i]); for(i = 0; i < 10; ++i) insert('0'+i, table[NUM][i]); } static void drop_tree_aux(MTree *root){ if(root){ drop_tree_aux(root->dot); drop_tree_aux(root->bar); free(root); } } void drop_tree(void){ drop_tree_aux(root); }

回答by abelenky

My very short and simple version::

我的非常简短和简单的版本::

##代码##

回答by usr2564301

A brute force approach is the easiest -- not as brute as you propose, though.

蛮力方法是最简单的——虽然不像你建议的那样蛮力。

  1. Create an array of inputstrings containing the Morse codes.
  2. Create an array of outputstrings containing what the strings from #1 represent (most of them will be a single character). Make sure this is in the exact same order as the array from #1. (You can do both at once using a 2-dimensional array or a structure, or possibly in even more advanced ways. Use what you know best.)
  3. Start of outer loop: initialize a destinationstring to empty.
  4. Read one character at a time from the input string, and:
    a. if it's a dash or dot, add it to the destination string;
    b. if not, end this loop.
  5. Repeat #4 until you encounter something not dash or dot. a. Compare the new string to each of the Morse codes in the array #1. When found, write the corresponding output code from the array #2.
    b. skip spaces in the input string;
    c. if you encounter the slash, write a space; and
    d. if you encounter the end of the input string, you are done.
  6. Repeat the loop at 3 until you encounter end-of-input.
  1. 创建一个包含摩尔斯电码的输入字符串数组。
  2. 创建一个输出字符串数组,其中包含 #1 中的字符串所代表的内容(其中大部分将是单个字符)。确保这与#1 中的数组的顺序完全相同。(您可以使用二维数组或结构,或者可能以更高级的方式同时执行这两项操作。使用您最了解的内容。)
  3. 外循环开始:将目标字符串初始化为空。
  4. 从输入字符串中一次读取一个字符,并且:
    a.如果是破折号或点,则将其添加到目标字符串中;
    湾 如果没有,结束这个循环。
  5. 重复#4,直到遇到不是破折号或点的东西。一种。将新字符串与数组 #1 中的每个莫尔斯电码进行比较。找到后,从数组#2 中写入相应的输出代码。
    湾 跳过输入字符串中的空格;
    C。如果遇到斜线,写一个空格;和
    d。如果遇到输入字符串的结尾,就完成了。
  6. 在 3 处重复循环,直到遇到输入结束。

回答by Meninx - メネンックス

Here is a commented code that answers your question !

这是一个注释代码,可以回答您的问题!

##代码##

Keep in mind that this is not an optimal solution because for instance the search for the pattern is linear instead you can use the binary search after sorting the array !

请记住,这不是最佳解决方案,因为例如模式的搜索是线性的,您可以在对数组进行排序后使用二分搜索!

Brievely, the code above can be improved !!

简而言之,上面的代码可以改进!!

Hope it helps anyway !!

无论如何希望它有帮助!!

回答by HerlDerp

##代码##

回答by BLUEPIXY

sample of split string by using strtok

使用 strtok 拆分字符串的示例

##代码##

回答by HerlDerp

i found the solution! :D credits to BLUEPIXY for the for(i=0,j=0;i<x;++i){ for(code = strtok(string[i], separator);code != NULL;code = strtok(NULL,separator)){ strcpy(destination[i][j++], code);} }

我找到了解决方案!:D 归功于 BLUEPIXY for(i=0,j=0;i<x;++i){ for(code = strtok(string[i], separator);code != NULL;code = strtok(NULL,separator)){ strcpy(destination[i][j++], code);} }

Thanks guys

谢谢你们

##代码##

回答by radhoo

m-oehm's answer is really good, as I find all the other approaches involving tables a bit redundant. I followed the binary tree encoder, and came out with an example code that is ready to use.

m-oehm的回答非常好,因为我发现所有其他涉及表格的方法都有些多余。我遵循了二叉树编码器,并得出了一个可以使用的示例代码。

The algorithm

算法

You'll need to start with the binary tree parsed in preorder, find the index of the letter you want to encode to morse, convert that to binary, ignore the first digit, and then just assign the zeros to dots, and the ones to dashes. It's really simple.

您需要从按顺序解析的二叉树开始,找到要编码为莫尔斯的字母的索引,将其转换为二进制,忽略第一个数字,然后将零分配给点,然后将那些分配给破折号。这真的很简单。

A C implementation exampleenter image description here

AC实现示例在此处输入图片说明

Also there is a full code example here.

也有一个完整的代码示例在这里