兔宝宝君000的博客

行万里路,读万卷书.

基于二叉树的局域网MorseCode的发收程序

为了测试一下新博客,这是以前的csdn里面导入的 原文地址

课题名:模拟电报通讯

要求:电报大家是都知道的。现在我想要大家用c语言做一个局域网内的电报通讯软件(无需界面,控制台程序即可)。中间会涉及到网络编程,摩尔斯电码解析(就是字符串处理)等知识。无需做的多复杂,我只要这些功能:

  • 电报功能的模拟。能收,能回复。
  • 将重要讯息存盘处理。
  • 摩尔斯电码的准确解析。无需中文,简单的英文即可。

下面我就说说我是怎么做的吧

首先网络部分,这个比较简单,看看例子,几个函数的调用,看看说明,然后研究一下就OK了。

存盘部分,也比较简单,用一个二级针指,把所有信息先记录下来,然后看用户有没有需要,不要的话free就完事了。

我想重点讲讲这个有趣的MorseCode(PS:这个一点一杠的真的很有意思,大家可以看看百度百科,还有一个段基于MorseCode的爱情)。好了,进入正题,其实MorseCode可不用要用枚举的,那样一个一个地写多麻烦啊,下面我来介绍一种基于二叉树实现的MorseCode。

先让大家看看一些符号的MorseCode:

Morse

有规律吗?答案是必然的!再看:

Morse

“嘀”声代表一点,“哒”声代表一横线,听到“嘀”就向右移动,听到“哒”就向左移动。例如你听到“哒嘀嘀”,就表示先向左一次,再向右两次,就会去到D那里。

有规律了吧,不信的可以自己去验证一下!好,有了 这些基础就是我们大展才华的奠基石了! 下面看一段代码:

生成MorseCode树

typedef struct tree 
{
    char data;
    struct tree *leftchild;
    struct tree *rightchild;
} MorseCode;

#define LENTREE sizeof(MorseCode)
char morse[100]={'#','T','M','O',',','0','$','$','9','$','$','.','$','8','$','$','G','Q','$','$','Z',/
'$','7','$','$','N','K','Y','$','$','C','$','$','D','X','$','$','B','$','6','$','$','E','A','W','J',/
'1','$','$','$','P','$','$','R','$','L','$','$','I','U','-','2','$','$','$','F','$','$','S','V',/
'3','$','$','$','H','4','$','$','5','$','$'};

int morse_x=-1;

void creat_tree(MorseCode **root)
{
    morse_x++;

    if (morse[morse_x] == '$') 
    {
        (*root) = NULL;
    }
    else 
    {
        (*root) = (MorseCode *) malloc (LENTREE);
        (*root)->data = morse[morse_x];
        creat_tree(&(*root)->leftchild);
        creat_tree(&(*root)->rightchild);
    }
    return ;
}

将字符串转为MorseCode

void preorder_letterTOmorse(MorseCode *root,char *morsecode,char *letter,int i,int *j)  
{  
    if (root)   
    {  
        if (root->data == letter[i])   
        {  
            morsecode[(*j)++] = ' ';  
            return ;  
        }  
        else   
        {  
            morsecode[(*j)++] = '_';  
            preorder_letterTOmorse(root->leftchild,morsecode,letter,i,j);  
            if (morsecode[(*j)-1] == ' ') return ;  
            (*j)--;  
            morsecode[(*j)++] = '.';  
            preorder_letterTOmorse(root->rightchild,morsecode,letter,i,j);  
            if (morsecode[(*j)-1] == ' ') return ;  
            (*j)--;  
            if (morsecode[(*j)] == ' ') return ;  
        }  
    }  
    return ;  
}  

void letterTOmorse(MorseCode *root, char **morsecode,char *letter)  
{  
    (*morsecode) = (char *) malloc(sizeof(char)*100);  
    strnset((*morsecode),'0',100);   
    int i=0,j=0;  
    while (letter[i]!='/0')  
    {  
        preorder_letterTOmorse(root,*morsecode,letter,i,&j);  
        i++;  
    }  
    (*morsecode)[j]='/0';  
}  

将MorseCode转为字符串

char preorder_morseTOletter(MorseCode *root,char *temp,int *j)  
{  
    (*j)++;  
    char result;  
    if (root)   
    {  
        if (temp[*j]=='/0')  
        {  
            return root->data;  
        }  
        if (temp[*j]=='_')   
        {  
            result=preorder_morseTOletter(root->leftchild,temp,j);  
            if (temp[*j]=='/0')  
            {  
                return result;  
            }  
        }  
        if (temp[*j]=='.')  
        {   
            result=preorder_morseTOletter(root->rightchild,temp,j);  
            if (temp[*j]=='/0')  
            {  
              return result;  
            }  
        }  
    }  
}

void morseTOletter(MorseCode *root, char *morsecode,char **letter)  
{  
    (*letter) = (char *) malloc(sizeof(char)*100);  
    char *temp = (char *) malloc(sizeof(char)*10);  
    int i=0,j=0,k=0;  
    while ( morsecode[i]!='/0')  
    {  
       j=0;  
       while(morsecode[i]=='.' || morsecode[i]=='_')  
       {  
           temp[j++]=morsecode[i++];  
       }  
       temp[j]='/0';  
       if ( morsecode[i]=='/0')  
       {  
            break;  
       }  
       else   
       {  
            i++;  
       }  
       j=-1;  
      (*letter)[k++]=preorder_morseTOletter(root,temp,&j);  
    }  
    (*letter)[k]='/0';  
    free(temp);  
    return ;  
}  

有了这些代码,是不是很方便地转换了? 还有就是,要加入更多字符的信息只要在创建树的时候加一字符就ok了,加上树的搜索效率,是不是感觉很爽啊!