算法竞赛入门经典(第2版)第4章 函数和递归

习题4-6 莫尔斯电码  UVa508

感悟。

1、阅读书中题目,从网站下载英文原题,重点在看输入输出数据与格式。

2、英文的阅读量还是比较大的,莫尔斯电码要靠上下文来猜,这点是弄明白了。

3、阅读完输入输入后,直接莫尔斯码对应字母,可能性太多。想到把可能的单词译成莫尔斯码,这样工作量会小许多。

4、继续阅读,思考,充分后再编码。

5、弄懂了‘?’的含义,莫尔斯码收到过多,或有缺失,找最接近的上下文单词。

6、‘!’弄了比较长时间,还一知半解,接续阅读,争取弄懂。读了一遍中文书,这样理解,因完全匹配的单词很多,在上下文单词中,遇到的第一个单词。

7、本题是处理多次不同莫尔斯编码,还是处理一次莫尔斯编码?

8、感觉题意理解得不是那么明白。

9、数据一一对应如何实现,一开始想到比较复杂的转换,后来一想采用结构体,采用数组,数据马上清晰了。

10、再读一遍英文原题,不读懂,编码的时候总觉得不放心。第一段完全读懂,第二段完全读懂,第三段完全读懂,第四段未完全读懂,有多个单词匹配,前面说选字符数最少的单词,后面说选第一次匹配的单词,到底怎么选,没搞明白,也就是样例中,不选IM,选EAT理由何在?第四段完全看懂,第五段完全看懂。全文读下来,问题就出现在第四段未完全读懂。

11、选取尽可能匹配的单词‘?’,也没花多长时间,算法有些类似选择排序,很快程序编好,测试样例通过。

12、应该是WA,三个原因,一是编码表的个数写死,26字母+10数字=36;二是‘!’没读懂;三是程序只能处理一次莫尔斯编码。

13、提交Runtime error。以上三个问题,在编码之前就留存,准备看看他人代码。

14、搜索了许多,这个说得比较好,http://www.th7.cn/Program/cp/201501/351062.shtml这题的意思是给定一些莫尔斯编码,给定一些已知字典,给定一些编码,求解这些编码的对应原文,如果可以精确匹配,则直接输出原单词,如果有多个可精确匹配的结果,则输出匹配结果里字典序最小的单词(紫书上说输出任意一个,这是错误的)并在末位加上“!”;如果无法精确匹配,则可以在编码的末尾增加或删除一些字符后匹配单词(增删应尽量小,就是找到增删最少的模糊匹配),无论增删后匹配一个还是多个,最后都要加上“?”,如果有多个模糊匹配结果(增删数相等),则输出字典序最小的匹配结果;如果无精确匹配也无模糊匹配结果,则输出整个给定字典里字典序最小的那个单词。看来前面理解正确。

15、将程序中的数组扩容10倍,提交Runtime error,看来得把重心放在程序处理上了。

16、对‘?’处理上有问题,做了修改,提交Runtime error,准备再看看他人程序。

17、好不容易,找到一个用C编写的程序,http://blog.csdn.net/aozil_yang/article/details/50253467,期中的#define MAXN 1000 + 5很有启发,马上在自个程序中,如法炮制,提交AC。没想到是这样一个结果。
18、马上动手查自个程序,看是哪出问题。经排查,出现在:morse[maxn];//morse[100+10] Runtime error morse[maxn] AC 2016-11-7 13:31整整花了两天时间,再阅读英文原题,The remainder of the input contains morse words separated by blanks or end-of-line characters.
A line containing only a single asterisk (“*”), possibly preceded or followed by blanks, terminates the
input. No morse word will have more than eighty (80) elements.确实没有提到morse words的个数。一直在此Runtimeerror,涨经验了。2016-11-7 13:31 AC

附上AC代码,编译环境Dev-C++4.9.9.2

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

#define INF 999
#define maxn 1000+10

int ccount;//code个数
int wcount;//上下文单词个数
int mcount;//morse单词个数
int p[100+10];//偏离单词长度
//结构体
struct morsecode{//字母编码
    char name;
    char namecode[20];//不超过6个
}code[50];//字母数字,不超过36个

struct contextword{//上下文单词
    char context[20];//不超过10个字母
    char contextcode[100];//不超过80个元素
}word[100+10]; //不超过100个

struct morseword{//莫尔斯单词
    char contextcode[100];
    char context[20];
}morse[maxn];//morse[100+10] Runtime error morse[maxn] AC 2016-11-7 13:31此处整整查了两天
//读取编码
void readcode(){
    int i;
    char t[10];
    ccount=0;
    while(scanf("%s",t)&&t[0]!='*'){
        code[ccount].name=t[0];
        scanf("%s",code[ccount].namecode);
        ccount++;
    }
/*    for(i=0;i<36;i++){
        scanf("%s%s",t,code[i].namecode);
        code[i].name=t[0];
    }*/
}

void printcode(){
    int i;
    for(i=0;i<ccount;i++){
        printf("%c %s\n",code[i].name,code[i].namecode);
    }
}
//读取上下文单词,进行编码
void readword(){
    char t[20];
    int i,j;
    int len;
    wcount=0;
    while(scanf("%s",t)&&t[0]!='*'){//读取单词
        strcpy(word[wcount].context,t);
        //将单词编码
        len=strlen(t);
        for(i=0;i<len;i++){
            for(j=0;j<ccount;j++){
                if(t[i]==code[j].name){
                    strcat(word[wcount].contextcode,code[j].namecode);
                    break;
                }
            }
        }
        
        wcount++;
    }
}

void printcontext(){
    int i;
    for(i=0;i<wcount;i++){
        printf("%s %s\n",word[i].context,word[i].contextcode);
    }
}
//读取morse word
void readmorse(){
    int i,j,k;
    int min;
    char t[100];
    int fcount;//匹配次数 find count
    int mlen,wlen;
    mcount=0;
    while(scanf("%s",t)&&t[0]!='*'){
        strcpy(morse[mcount].contextcode,t);
        
        //莫尔斯解码
        fcount=0;
        for(i=0;i<wcount;i++){
            if(strcmp(word[i].contextcode,t)==0){
                fcount++;
                if(fcount==1)//匹配一次
                    strcpy(morse[mcount].context,word[i].context);
                else{//匹配多次
                    strcat(morse[mcount].context,"!");
                    break;
                }
            }
        }
        if(fcount==0){//未匹配成功
            memset(p,0,sizeof(p));
            mlen=strlen(t);
            //上下文单词匹配长度计算
            for(i=0;i<wcount;i++){//取出上下文单词
                k=0; //匹配长度
                wlen=strlen(word[i].contextcode);
                for(j=0;j<mlen;j++){
                    if(j<=wlen){//此处漏了=,现已添加2016-11-7
                        if(word[i].contextcode[j]==morse[mcount].contextcode[j])
                            k++;
                    }else
                        break;
                }
                if(k==mlen)//原k>mlen,不可能,k最多=mlen ,wlen>mlen,删除多余
                    p[i]=wlen-mlen;
                else if(k<mlen&&k==wlen)//k<mlen,增加一些
                    p[i]=mlen-wlen;
                else//k<mlen k<wlen ,不匹配
                    p[i]=INF;        
            }
            
            min=p[0];
            j=0;
            for(i=0;i<wcount;i++){//找出差异最小的位置。
                if(p[i]<min){
                    min=p[i];
                    j=i;
                }
            }
            strcpy(morse[mcount].context,word[j].context);
            strcat(morse[mcount].context,"?");
        }
         
        mcount++;
    }
}

void printword(){
    int i=0;
    for(i=0;i<mcount;i++)
        printf("%s\n",morse[i].context);
}

int main(){
    readcode();
    //printcode();
    readword();
    //printcontext();
    readmorse();
    printword();
    return 0;
}

习题4-6 莫尔斯电码 UVa508相关推荐

  1. uva508 莫尔斯电码(Morse Mismatches)

    首先我理解错了题意,在这篇文章找到了UVa 508 Morse Mismatches(莫尔斯电码) 这题的意思是给定一些莫尔斯编码,给定一些已知字典,给定一些编码,求解这些编码的对应原文,如果可以精确 ...

  2. 设计一个莫尔斯电码电报机

    //设计一个电报机 //要导入的包 import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.Action ...

  3. 树莓派作品2_莫尔斯电码

    一.创意来源 莫尔斯电码历史悠久,我从小时候就听说过莫尔斯电码了伟大了,不过直至今日我都没有机会过过手瘾,亲手用莫尔斯电码来输出一些有意义的句子. 不过有了树莓派,一切都不成问题,只要两个按钮,就能帮 ...

  4. [AHK]将字符转换成莫尔斯电码

    这个程序可以在记事本中使用.当用户按下空格键时,程序会获取当前选中的文本,并将其转换为莫尔斯电码播放出来.如果用户选中的文本包含非摩尔斯电码字符,程序会自动忽略它们. 将字符转换成莫尔斯电码 ; 这个 ...

  5. 莫尔斯电码对照表_使用莫尔斯电码编码纯文本

    莫尔斯电码对照表 This began as a thought experiment while waiting for patches to install on my system. 这是在等待 ...

  6. 莫尔斯电码(Python)

    莫尔斯电码采用了短脉冲和长脉冲 (分别为点和点划线) 来编码字母和数字. 例如,字母"A"是点划线,"B"是点划线点点.如文件 Mos.txt 文件所示. A ...

  7. UVA-508 莫尔斯电码 题解答案代码 算法竞赛入门经典第二版

    https://github.com/jzplp/aoapc-UVA-Answer 这个题目就是在考验英语水平呀!(或者题目本身也写的不清楚) 尤其是多个完全匹配(!)和模糊匹配(?)的情况,我题意看 ...

  8. 莫尔斯翻译器编码 c语言,翻译莫尔斯电码

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include "windows.h" #include "stdio.h" char             ...

  9. c语言莫尔斯编码互译,翻译莫尔斯电码

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include "windows.h" #include "stdio.h" char             ...

最新文章

  1. Eclipse安装GoClipse
  2. ios 图片 相册 存储方式
  3. TCPIP,Http,Socket的区别
  4. nextcloud+nginx+mysql,Ubuntu搭建Nginx-Nextcloud环境
  5. excel记账本模板_原来这才是老板最喜欢看的财务报表!这些模板送你,录入自动生成...
  6. 【AI视野·今日CV 计算机视觉论文速览 第179期】Tue, 25 Feb 2020
  7. 人走茶凉!三星关闭最后一家中国手机工厂 因为打不过其他国产厂商?
  8. NSMutableArray遍历删除注意事项
  9. 16年的大数据经验,为了搞定数字化转型,我和老板做了个赌注
  10. golang 中io包用法(一)
  11. iOS开发 控件不能绑定拖动到视图ViewController连接的解决方法
  12. Prometheus 的云上 MySQL 监控实践
  13. Linux命令详解词典高频命令(1)
  14. h3c服务器通过pxe安装系统,h3c服务器设置pxe启动
  15. ubantu 搭建我的世界java服务器 spigot核心
  16. Pycharm中Python包的下载与使用
  17. SBC音频编解码算法浅析
  18. 万兆网络传输速度测试_iperf测试万兆网卡tcp性能
  19. CH341A及XTW 2两种SPI FLASH烧录器的硬件使用说明_20220920【可用于升级主板BIOS】
  20. OpenGL字体绘制

热门文章

  1. 低成本搭建一台家庭存储服务器:前篇
  2. Spring boot 整合disruptor
  3. 怎么打开.net服务器文件,asp.net 打开服务器文件
  4. 2017第八届蓝桥杯(C/C++ B组)C语言解法---等差数列
  5. 仓储管理中,周转箱管理的要点是什么
  6. 使用BleLib的轻松搞定Android低功耗蓝牙Ble 4.0开发详解
  7. tomcat启动时中文乱码
  8. mysql中括号的表达_mysql-在通配符的SQL语句中将方括号括起来
  9. 银行计算机考试范围,银行考试内容
  10. VS2013下编译osip和exosip的5.0版本静态库及搭建和简单例子的实现