算法竞赛入门经典 习题4-6

UVa508

Morse Mismatches

各种地方描述的这道题目不一样。精确匹配时,有的地方说输出最短的(长度相同再按照字典序排序),有的地方说输出字典序最小的;模糊匹配时,必须是删除最少字符后完全匹配,或者增加最少字符后精确匹配才可以输出,输出跟字典序好像没关系(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
*
.--.....-- .....--....
--.----.. .--.-.----..
.--.....-- .--.
..-.-.-....--.-..-.--.-.
..-- .-...--..-.--
---- ..--
*
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值