算法习题---4-6莫尔斯电码(UVa508)

一:题目

A-Z0-9分别对应一些莫尔斯电码字符串
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
题目给出一系列莫尔斯电码(以空格隔开),我们按照之前的A-Z-9去对这些莫尔斯电码进行解析(必须匹配我们上面提供的单词)
匹配形式有:
精确匹配--一个莫尔斯电码串只有一个单词匹配
多重匹配--一个莫尔斯电码可以精确匹配多个单词,我们只取第一个匹配的单词,并在单词后面加上“!”
模糊匹配--由于题目提供的莫尔斯电码串可能在传输中被截断,所以会出现该莫尔斯电码长度比原来应该匹配的单词短,我们找到长度最匹配(最相近)的单词进行输出,并在后面加上“?”

(一)样例输入

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
*        //代表结束此类输入
.--.....-- .....--....  //这是我们要匹配的莫尔斯电码串,每个莫尔斯电码串用空格或者换行隔开
--.----.. .--.-.----..
.--.....-- .--.
..-.-.-....--.-..-.--.-.
..-- .-...--..-.--
---- ..--
*

(二)样例输出

WHAT
HATH
GOD
WROTH?
WHAT
AN
EARTHQUAKE
EAT!
READY
TO
EAT!

二:代码实现

使用C语言实现过于麻烦,所以使用C++中map进行数据映射,更加方便
#include <iostream>
#include <string>
#include <map>

using namespace std;

map<char, string> CM;  //保存字符--莫尔斯电码
map<string, string> WM;  //保存单词--莫尔斯电码

获取字符和单词的莫尔斯电码映射

void getMorseMap()
{
    int i;
    char ch;
    string Morse,Words;
    while ((cin >> ch)&&ch!='*')
    {
        cin >> Morse;
        CM.insert(pair<char, string>(ch, Morse));
    }

    while ((cin>>Words)&&Words[0]!='*')
    {
        Morse = "",i=0;
        while (Words.length()!=i)
            Morse += (*CM.find(Words[i++])).second;
        WM.insert(pair<string, string>(Words, Morse));
    }
}

比较两个莫尔斯电码的长度,返回匹配不成功的长度差

int getComplen(string src, string obj)
{
    int i = 0;
    for (i = 0; src[i] == obj[i]; i++);
    return obj.length() - i;
}

进行莫尔斯电码匹配单词

void printMorseData()
{
    bool flag = false;
    string MorseWord;
    int min,len;
    map<string, string>::iterator iter, ret;
    while (cin >> MorseWord&&MorseWord[0] != '*')
    {
        flag = false;
        //精确匹配
        for (iter = WM.begin(); iter != WM.end();iter++)
            if (iter->second == MorseWord)
                if (flag) cout << "!";
                else cout << iter->first, flag = true;
        //模糊匹配 由于摩斯密码只能截断,所以获取的摩斯密码只能比原来的数据短
        if (!flag)
        {
            min = 80;
            for (iter = WM.begin(); iter != WM.end(); iter++)
                if (iter->second.length() > MorseWord.length())
                {
                    len = getComplen(MorseWord, iter->second);
                    if (len < min)
                        min = len, ret = iter;
                }
            cout << ret->first << "?";
        }
        cout << endl;
    }
}

主函数

void main()
{
    FILE* fp = freopen("data6.in", "r", stdin);
    freopen("data6.out", "w", stdout);

    ios::sync_with_stdio(false);  //使得cin cout的效率同scanf和printf一样

    getMorseMap();    //获取映射数据
    printMorseData();    //打印摩斯数据

    freopen("CON", "r", stdin);
    freopen("CON", "w", stdout);
}
原文地址:https://www.cnblogs.com/ssyfj/p/11157995.html