算法习题---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); }