Morse Mismatches UVA - 508 map+前缀字符串

建立字符到对应Morse密码的映射map1。
每输入一个单词,通过map1将每一个字符翻译成Morse密码,建立所有密码到对应单词的映射map2。
对应输入的Morse密码M,在map2中查找是否有该密码和对应单词,单词数大于1多输出一个"!"。不存在对应,查找符合条件的增删Morse密码。在M的基础上增加或者删除和已知map密码相同,那么M不正是map密码的前缀,或者相反。找到增删密码长度差最小的那个输出即可。可以使用map<int, string>存放int放长度差,string存储单词,map本身就是按key排序的,直接输出第一个元素即可。

#include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;
map<char, string> morse;//字符到Morse密码的映射
map<string, vector<string> > word;//Morse密码串到单词的映射
/*
 * 判断a是否是b的前缀
 * @prama a 字符串a
 * @prmaa b 字符串b
 * @return a是b的前缀返回true,否则返回false
*/
bool isPre(const string& a, const string& b)
{
    return a.size() < b.size() && b.compare(0, a.size(), a) == 0;
}
/*
* *对Morse密码串a的翻译
* @parma a Morse密码串
*/
void slove(const string& a)
{
    if (word.count(a))//密码串与已知密码串匹配
    {
        auto v = word[a];
        cout << v.front();//返回第一个
        if (v.size() > 1) cout << "!";//匹配单词数大于1个
        cout << endl;
        return ;
    }
    map<int, string> ans;//模糊单词到单词的增删个数到单词的映射
    for (auto p: word)
    {
        string tmp = p.first;//密码
        //a与密码比较,如果a是密码的前缀,处理删除字符
        //密码是a的前缀,处理增加字符
        if (isPre(a, tmp)) ans[tmp.size() - a.size()] = p.second.front();
        else if (isPre(tmp, a)) ans[a.size() - tmp.size()] = p.second.front();
    }
    //mp本身就是按key存放的,直接输出第一个元素即可
    cout << ans.begin()->second << "?" << endl;
}
int main()
{
    string a, b;
    while (cin >> a && a != "*")
    {
        cin >> b;
        morse[a[0]] = b;
    }
    while (cin >> a && a != "*")
    {
        b.clear();
        for (auto x : a) b += morse[x];
        word[b].push_back(a);//密码对应串
    }
    while (cin >> a && a != "*")
        slove(a);
    return 0;
}

发布了51 篇原创文章 · 获赞 19 · 访问量 8297

猜你喜欢

转载自blog.csdn.net/WxqHUT/article/details/98887537
今日推荐