UVa508
各种地方描述的这道题目不一样。精确匹配时,有的地方说输出最短的(长度相同再按照字典序排序),有的地方说输出字典序最小的;模糊匹配时,必须是删除最少字符后完全匹配,或者增加最少字符后精确匹配才可以输出,输出跟字典序好像没关系(uDebug上的测试用例就是先按长度、再按字典序,但是我AC的代码是按照字典序的),而且不满足上述条件的也不用考虑。
下面代码中32行的注释可有可无,反正都AC了。
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <sstream>
using namespace std;
void print(const vector<string> &vsMorse)
{
for (auto iter = vsMorse.begin(); iter != vsMorse.end(); iter++)
{
cout << *iter << endl;
}
}
void print(const map<string, string> &mssDic)
{
for (auto iter = mssDic.begin(); iter != mssDic.end(); iter++)
{
cout << iter->first << ' ' << iter->second << endl;
}
}
string getPerfectMatch(const map<string, string> &mssDic, const string &strWord)
{
string strRet;
int match = 0;
for (auto iter = mssDic.begin(); iter != mssDic.end(); iter++)
{
if (iter->second == strWord){
if (match == 0/* || iter->first.size() < strRet.size()*/) strRet.assign(iter->first);
match++;
}
}
if (match > 1){
strRet.push_back('!');
}
return strRet;
}
string getFuzzyMatch(const map<string, string> &mssDic, const string &strWord)
{
string strRet;
size_t cnt = 80;//编码最长80
size_t del = 0, add = 0;
for (auto iter = mssDic.begin(); iter != mssDic.end(); iter++)
{
size_t idx = 0;
for (; idx < iter->second.size() && idx < strWord.size(); idx++)
{
if (iter->second[idx] != strWord[idx]) break;
}
//需要删除才可以匹配
if (idx == iter->second.size() &&
iter->second.size() < strWord.size()){
del = strWord.size() - iter->second.size();
if (del < cnt){
strRet.assign(iter->first);
strRet.push_back('?');
cnt = del;
}
}
//需要增加才可以匹配
else if (idx == strWord.size() &&
iter->second.size() > strWord.size()){
add = iter->second.size() - strWord.size();
if (add < cnt){
strRet.assign(iter->first);
strRet.push_back('?');
cnt = add;
}
}
}
return strRet;
}
int main()
{
string strLine, strPlain, strMorse;
vector<string> vsMorse(26 + 10, "");
while (getline(cin, strLine)){
if (strLine.empty()) continue;
else if (strLine == "*") break;
istringstream iss(strLine);
iss >> strPlain >> strMorse;
if (isalpha(strPlain[0])){
vsMorse[strPlain[0] - 'A'] = strMorse;
}
else if (isdigit(strPlain[0])){
vsMorse[strPlain[0] - '0' + 26] = strMorse;
}
}
//print(vsMorse);
map<string, string> mssDic;
while (getline(cin, strLine)){
if (strLine.empty()) continue;
else if (strLine == "*") break;
for (auto ch : strLine)
{
if (isalpha(ch)) mssDic[strLine] += vsMorse[ch - 'A'];
else if (isdigit(ch)) mssDic[strLine] += vsMorse[ch - '0' + 26];
}
}
//print(mssDic);
string strMatch, strWord;
while (getline(cin, strLine)){
if (strLine.empty()) continue;
else if (strLine == "*") break;
istringstream iss(strLine);
while (iss >> strWord){
strMatch = getPerfectMatch(mssDic, strWord);
if (!strMatch.empty()) cout << strMatch << endl;
else{
strMatch = getFuzzyMatch(mssDic, strWord);
cout << strMatch << endl;
}
}
}
return 0;
}
/*
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
*
.--.....-- .....--....
--.----.. .--.-.----..
.--.....-- .--.
..-.-.-....--.-..-.--.-.
..-- .-...--..-.--
---- ..--
*
*/