https://vjudge.net/contest/174376#problem/E
读题很关键。。。
题意:输入每个字母的编码,一个词典,和若干个编码。对于每个编码判断他可能是哪个单词。如果有多个精确匹配,输出第一个并且后面加上‘!’,如果在编码尾部删除或添加尽可能少的字符可以匹配,在后面加上‘?’。
解决:把词典里的单词存成编码,然后把每个输入的编码比较就好。
细节:自己没做出来,主要是思路太乱,看了别人的代码,很精炼,也有很多不懂的STL里的东西。
1.string::substr(首地址,长度)basic_string::substr
basic_string substr(size_type _Off = 0,size_type _Count = npos) const;
参数
_Off
所需的子字符串的起始位置。字符串中第一个字符的索引为 0,默认值为0.
_Count
复制的字符数目
返回值一个子字符串,从其指定的位置开始
2.迭代器 rbegin
c.begin() 返回一个迭代器,它指向容器c的第一个元素
c.end() 返回一个迭代器,它指向容器c的最后一个元素的下一个位置
c.rbegin() 返回一个逆序迭代器,它指向容器c的最后一个元素
c.rend() 返回一个逆序迭代器,它指向容器c的第一个元素前面的位置
3.map.second
map里有两个值< a, b > first代表前值,second代表后值
#include <iostream>
#include <cstdio>
#include <cstring>
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f;
map<char, string> morse;
map<string, string> dic;
int judge(string a, string b){
if(a == b) return 0;//相等
if(a.size() > b.size()) swap(a, b);//如果保证a的长度小于b
if(a == b.substr(0, a.size())) return b.size() - a.size();//如果a和b的前边一样,那么就可以增加或删减字符使它们一样,返回长度差
return INF;//如果不一样,那就不能通过增加或删除使它们一样,那么就返回最大值
}
string solve(const string &s){
string ans = "";
int mmin = INF;//初始化
for(map<string, string>:: iterator it = dic.begin(); it != dic.end(); ++it){
int d = judge(s, it->second);
if(!d && !mmin && *ans.rbegin() != '!'){ ans += "!"; return ans; }//说明精确匹配两次了,直接返回就ok了
else if(d <= mmin) ans = it->first;//不精确匹配,
mmin = min(d, mmin);
// if(s == ".--.-.----..") cout << mmin << endl << it->second << endl;
}
if(mmin) ans += "?";//如果是不精确匹配
}
int main(){
// freopen("in.txt", "r", stdin);
string s, ch;
while(cin >> ch && ch != "*"){
cin >> s;
morse[ch[0]] = s;//构造字符map
}
while(cin >> s && s != "*"){
for(int i = 0; i < s.size(); ++i)
dic[s] += morse[s[i]];//构造字典
}
// cout << dic["WROTH"] << endl;
while(cin >> s && s != "*")
cout << solve(s) << endl;
return 0;
}
代码来源:http://www.cnblogs.com/dwtfukgv/p/5572356.html