【问题标题】:Morse Code Converter in CC中的摩尔斯电码转换器
【发布时间】:2015-03-18 16:06:25
【问题描述】:

是的,它的功课 我们假设有 char 2D 数组保存字符,大小限制为 255 char char string[100][255];

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

示例输入

2

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

 .--- --- -.- .

样本输出

  • 案例#1:

    HELLO WORLD
    
  • 案例#2:

    JOKE
    

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

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

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

【问题讨论】:

  • 这绝对是家庭作业的味道。你的问题也措辞不好。值得重写它,以便这里有一个实际的问题。目前,这只是一堆杂乱无章的信息,无法说明您的问题。
  • 好的,我会直接编辑它

标签: c encoder decoder


【解决方案1】:

您已经发现可以在每个莫尔斯信号上进行分支,并且将所有这些硬编码为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 * *

可以在middle sections of the Wikipedia entry on Morse code 中以(稍微)更漂亮的形式找到同一棵树。 (最下面一行的星号表示不是英文字母表中 26 个字母之一的编码。)

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

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

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

您可以看到从节点 n 向左分支会将您带到节点 2*n,而向右分支会将您带到索引为 2*n + 1 的右邻居。建立索引,从 1 开始,然后在数组中查找您的字母:

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

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

【讨论】:

  • 感谢您的想法.. 但我从未尝试过制作一棵树.. 所以 :( 是的,我知道它是如何工作的,但我们从未讨论过如何创建它们
  • 嗯,重点是,这实际上不是一棵树,而是一个线性数组。一棵扁平的树,如果你喜欢的话。无论如何,您似乎有很多更直接的解决方案可供选择。
【解决方案2】:
#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 == '\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 == '\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]='\0';
                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 == '\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);
}

【讨论】:

  • 这行得通,但大多数代码从来没有教给我..无论如何..这也不是要求用户输入..输入已经放在代码中..哦好吧,我会尝试更多地学习此代码..谢谢
  • 据我了解,您没有被问及接受用户的输入
  • 没关系,这是我的错,没有在问题中指出它..我编辑了它,但仍然缺少一些东西..我想我必须添加它,否则为时已​​晚现在..大声笑
  • “程序需要:将用户输入的莫尔斯电码更改为字母/英文字母(大写字母)”等等..实际上我确实澄清了我想我不需要编辑它哦,哈哈
【解决方案3】:

我的非常简短的版本::

#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;
}

【讨论】:

    【解决方案4】:

    蛮力方法是最简单的方法——不过,不像您建议的那样蛮力。

    1. 创建一个包含莫尔斯电码的输入字符串数组。
    2. 创建一个 output 字符串数组,其中包含来自 #1 的字符串所代表的内容(其中大部分将是单个字符)。确保它与 #1 中的数组的顺序完全相同。 (您可以同时使用二维数组或结构,也可以使用更高级的方式同时执行这两项操作。使用您最了解的方法。)
    3. 外循环开始:将 destination 字符串初始化为空。
    4. 从输入字符串中一次读取一个字符,并且:
      一种。如果是破折号或圆点,请将其添加到目标字符串;
      湾。如果没有,结束这个循环。
    5. 重复 #4 直到遇到不是破折号或圆点的内容。 一种。将新字符串与数组 #1 中的每个摩尔斯电码进行比较。找到后,从数组 #2 中写入相应的输出代码。
      湾。跳过输入字符串中的空格;
      C。如果遇到斜线,请写一个空格;和
      d。如果你遇到输入字符串的结尾,你就完成了。
    6. 在 3 处重复循环,直到遇到输入结束。

    【讨论】:

    • char input[36]={"-. ","-... ","-.-. ","-.. ",". "} char output[36]={'A','B','C','D','E'} 你是这个意思吗?
    • char input[36] 仅包含像 char input[36]={'A' ,'B', ... 这样的字符字符。如果你想在数组中存储字符串,你有两种可能,但我推荐这个char input[number of strings][maximum letters in each string]另一个是char* input[number of strings]
    • 在这种情况下,您需要在free() 之后使用malloc() 分配空间,或者像我在回答中所做的那样初始化它,但在这种情况下您不能修改数组的内容!
    【解决方案5】:

    这是回答您问题的注释代码!

    #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;
    }
    

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

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

    希望对你有帮助!!

    【讨论】:

    • 虽然我理解它遵循 ASCII 表.. 我仍然需要添加数字.. 我还需要修复代码中的情况.. 但我明白了。
    • 你使用了goto,你可以很容易地使用else
    • else { p=strtok(NULL,"\t \n"); continue;} 更准确!谢谢@Jongware! :)
    【解决方案6】:
    #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]!='\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?
    

    【讨论】:

    • 使用 strcmp 比较字符串。 if (i==0){ gets(string[0]); } 似乎是多余的。
    • 如果用户输入空格它会跳过并将其保存到数组目标中的另一行,我将其按空格分割,这样它会逐个字母并考虑空格。跨度>
    • if(i==0){gets(string[0]);} 出于某种原因在我输入病例数时存在.. 它跳过了string[0]...
    • 啊,是的。这需要换行符。(scanf("%d", &amp;x))
    • 你可以。 BTW 我想你已经提出了使用 strtok 来分割字符串,但是你不使用它有什么原因吗?
    【解决方案7】:

    使用 strtok 分割字符串的示例

    #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;
    }
    

    【讨论】:

    • 我希望我能投票,但我不能,哈哈,我需要 15 个代表哦,好吧,谢谢
    • 我可以打印一个字母..但我无法打印输入中的所有字母..
    • 更具体地说......我想知道这段代码是如何工作的......` for(code = strtok(string[i], separator); code != NULL; code = strtok(NULL, separator) ){ printf("'%s'\n", 代码); strcpy(目的地[j++],代码);`
    • 我无法打印输入中的所有字母。您需要从表格循环中搜索每个字符(编码代码)。 for(j=0,m=0;j&lt;37;j++){ : 37 不是输入的字符数,是表数。
    【解决方案8】:

    我找到了解决方案! :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);} }

    谢谢大家

    #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;
    }
    

    【讨论】:

      【解决方案9】:

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

      算法

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

      C 实现示例

      还有一个完整的代码示例here

      【讨论】:

        猜你喜欢
        • 2010-12-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-12
        • 2013-01-09
        • 1970-01-01
        • 1970-01-01
        • 2020-04-22
        相关资源
        最近更新 更多