/* 这题本来没什么思路,后来查了题解,发现如果用map来做,会很方便简洁 题解见blog: http://www.cnblogs.com/dwtfukgv/p/5572356.html */
#include <cstdio> #include <iostream> #include <map> #include <string> using namespace std; map<char, string> morse; map<string, string> dic; const int INF = 0x3f3f3f3f; typedef map<string, string>::iterator pointer; //#define debug int judge (string a, string b) { if (a == b) return 0; //完全匹配 if (a.size() > b.size()) swap(a, b); // 如果保证a的长度小于b,交换之后,就涵盖了增删的两种情况;最终solve函数中的mmin,变为了变化量的绝对值的最小值 if (a == b.substr(0, a.size())) return b.size() - a.size(); //如果 b 的前边和a一样,那么就可以增加或删减字符使它们一样,返回长度差 return INF; } string findword(const string& s) { string ans = ""; int mmin = INF, t; for (pointer i = dic.begin(); i != dic.end(); i++) { t = judge(s, i->second); if (!t && !mmin) { ans += "!"; return ans; } //两次精确匹配,加 "!" 后直接返回即可 //关于反向迭代器rbegin: http://blog.csdn.net/kjing/article/details/6936325 if (t < mmin) ans = i->first; mmin = min(t, mmin); } if (mmin) ans += "?"; //若未能精确比配,加"?" return ans; } int main() { #ifdef debug freopen("E:\in.txt", "r", stdin); freopen("E:\out.txt", "w", stdout); #endif string s, ch; while (cin >> ch) { if (ch == "*") break; cin >> s; morse[ch[0]] = s; // 构造每个字母的Morse编码 } while (cin >> s && s != "*") { for (int i = 0; i < s.size(); i++) dic[s] += morse[s[i]]; //找出所有单词的编码 // cout << "test: " << dic[s] << endl; } while (cin >> s && s != "*") { cout << findword(s) << endl; } #ifdef debug fclose(stdin); fclose(stdout); #endif return 0; }