508 - Morse Mismatches

Samuel F. B. Morse is best known for thecoding scheme that carries his name. Morse code is still used in internationalradio communication. The coding of text using Morse code is straightforward.Each character (case is insignificant) is translated to a predefined sequenceof dits and dahs (the elements of Morsecode). Dits are represented as periods (``.'') and dahs are represented ashyphens or minus signs (``-''). Each element is transmitted by sending a signalfor some period of time. A dit is rather short, and a dah is, in perfectlyformed code, three times as long as a dit. A short silent space appears betweenelements, with a longer space between characters. A still longer spaceseparates words. This dependence on the spacing and timing of elements meansthat Morse code operators sometimes do not send perfect code. This results indifficulties for the receiving operator, but frequently the message can bedecoded depending on context.


In this problem we consider reception of words in Morse code without spacingbetween letters. Without the spacing, it is possible for multiple words to becoded the same. For example, if the message ``dit dit dit'' were received, itcould be interpreted as ``EEE'', ``EI'', ``IE'' or ``S'' based on the coding schemeshown in the sample input. To decide between these multiple interpretations, weassume a particular context by expecting each received word to appear in adictionary.


For this problem your program will read a table giving the encoding of lettersand digits into Morse code, a list of expected words (context), and asequence of words encoded in Morse code (morse). These morse words maybe flawed. For each morse word, your program is to determinethe matching word from context, if any. If multiple wordsfrom context match morse, or if no word matchesperfectly, your program will display the best matching word and a mismatchindicator.


If a single word from context matches morse perfectly,it will be displayed on a single line, by itself. If multiple context wordsexist for a given morse, the first matching word will be displayedfollowed by an exclamation point (``!'').


We assume only a simple case of errors in transmission in which elements may beeither truncated from the end of a morse word or added to theend of a morse word. When no perfect matches for morse arefound, display the word from context that matches the longestprefix of morse, or has the fewest extra elements beyond those in morse.If multiple words in context match using these rules, any of thesematches may be displayed. Words that do not match perfectly are displayed witha question mark (``?'') suffixed.


The input data will only contain cases that fall within the preceding rules.

Input 

The Morse code table willappear first and consists of lines each containing an uppercase letter or adigit C, zero or more blanks, and a sequence of no more than six periods andhyphens giving the Morse code for C. Blanks may precede or follow the items onthe line. A line containing a single asterisk (``*''), possibly preceded orfollowed by blanks, terminates the Morse code table. You may assume that therewill be Morse code given for every character that appears in the context section.


The context section appears next, with one word per line,possibly preceded and followed by blanks. Each word in context willcontain no more than ten characters. No characters other than upper caseletters and digits will appear. There will be at most 100 context words.A line containing only a single asterisk (``*''), possibly preceded or followedby blanks, terminates the context section.


The remainder of the input contains morse words separated by blanks orend-of-line characters. A line containing only a single asterisk (``*''),possibly preceded or followed by blanks, terminates the input. No morse wordwill have more than eighty (80) elements.

Output 

For each input morse word, display the appropriate matching word from context followed by an exclamation mark (``!'') or questionmark (``?'') if appropriate. Each word is to appear on a separate line startingin column one.

Sample Input 

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

*

AN

EARTHQUAKE

EAT

GOD

HATH

IM

READY

TO

WHAT

WROTH

*

.--.....--   .....--....

--.----..  .--.-.----..

.--.....--   .--.

..-.-.-....--.-..-.--.-.

..--  .-...--..-.--

----       ..--

*

Sample Output 

WHAT

HATH

GOD

WROTH?

WHAT

AN

EARTHQUAKE

EAT!

READY

TO

EAT!

 

 

运行时错误但是没找出错误的代码:

#include<iostream>

#include<string>

#include<map>

#include<algorithm>

using namespacestd;

 

map<char,string>mapcs;

map<string,string>mapss;

map<string,string>::iteratorit;

 

string tran(strings);

stringoperate(string s);

int far(strings1,string s2);

 

int main()

{

    string str1,str2;

 

   while(cin>>str1&&str1!="*")

    {

        cin>>str2;

        mapcs[str1[0]]=str2;

    }

 

    while(cin>>str1&&str1!="*")

    {

        mapss[str1]=tran(str1);

    }

 

   while(cin>>str1&&str1!="*")

    {

        cout<<operate(str1)<<endl;

    }

}

 

string tran(strings)

{

    string ans="";

    for(int i=0; i<s.size(); i++)

    {

        ans=ans+mapcs[s[i]];

    }

    return ans;

}

 

stringoperate(string s)

{

    it=mapss.begin();

    int dis=far(it->second,s);

    string ans=it->first;

 

    while(it!=mapss.end())

    {

        it++;

        int d=far(it->second,s);

        if(d<dis)

        {

            dis=d;

            ans=it->first;

        }

        elseif(d==dis&&d==0&&ans[ans.size()-1]!='!')

        {

            ans=ans+"!";

            return ans;

        }

    }

 

    if(dis!=0)

    {

        return ans+"?";

    }

    else

    {

        return ans;

    }

}

 

int far(strings1,string s2)

{

    if(s1==s2)

    {

        return 0;

    }

    if(s1.size()>s2.size())

    {

        swap(s1,s2);

    }

    if(s1==s2.substr(0,s1.size()))

    {

        return s2.size()-s1.size();

    }

    else

    {

        return 10000;

    }

}

 

 

参考答案代码:

#include<algorithm>

#include<iostream>

#include<map>

#include<string>

using namespacestd;

const int inf =10000;

 

map<char,string> unit_code;

map<string,string> dict;

 

int dist(string a,string b)

{

    if (a == b)

    {

        return 0;

    }

    if (b.size() < a.size())

    {

        swap(a, b);

    }

    // a必须是b的子串

    if (a != b.substr(0,a.size()))

    {

        return inf;

    }

    else

    {

        return b.size()-a.size();

    }

}

 

stringencode(string& s)

{

    string ans;

    for (int i = 0; i < s.size(); i++)

    {

        ans = ans + unit_code[s[i]];

    }

    return ans;

}

 

stringdecode(string s)

{

    map<string, string>::iterator it =dict.begin();

    string ans = it->first;

    int dis = dist(it->second, s);

    while (++it != dict.end())

    {

        int d = dist(it->second, s);

        if (d < dis)

        {

            ans = it->first, dis = d;

        }

        else if (d == dis && d==0&& ans[ans.size()-1] != '!')

        {

            ans = ans + "!";

        }

    }

    if (dis)

    {

        ans = ans + "?";

    }

    return ans;

}

 

int main()

{

    string s1, s2;

    while (cin >> s1, s1 !="*")

    {

        cin >> s2;

        unit_code[s1[0]] = s2;

    }

    while (cin >> s1, s1 !="*")

    {

        dict[s1] = encode(s1);

    }

    while (cin >> s1 && s1 !="*")

    {

        cout << decode(s1) <<"\n";

    }

    return 0;

}

这题的意思是给定一些莫尔斯编码,给定一些已知字典,给定一些编码,求解这些编码的对应原文,如果可以精确匹配,则直接输出原单词,如果有多个可精确匹配的结果,则输出匹配结果里字典序最小的单词(紫书上说输出任意一个,这是错误的)并在末位加上“!”;如果无法精确匹配,则可以在编码的末尾增加或删除一些字符后匹配单词(增删应尽量小,就是找到增删最少的模糊匹配),无论增删后匹配一个还是多个,最后都要加上“?”,如果有多个模糊匹配结果(增删数相等),则输出字典序最小的匹配结果;如果无精确匹配也无模糊匹配结果,则输出整个给定字典里字典序最小的那个单词。

实现方面,看网上标程是用映射写的(也难怪自己没发现字典序这个关键词,映射里的元素直接就是排好序的,用映射看来很简单啊。。。= =)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值