《算法竞赛入门经典》—习题4-6:Morse Mismatches

思路分析

已知字符编码表,接受的单词表(context),现给出摩尔斯电码,根据规则解码。规则如下:

  • 1个精确匹配:直接输出
  • 多个精确匹配:输出字典序最小/context中最前面的都对(原题描述有些歧义fewest character长度最短?)
  • 0个精确匹配:找出最小模糊匹配,即两个字符串存在这样的关系:a是b的子串/b是a的子串,且二者长度相差最小(若有多个满足,输出任意单词即可)

算法设计

  • 惯性思维:想直接从摩尔斯密码来解码,那么必须dfs许多情况,过于复杂。

  • 逆向思维:根据给定的字符编码表和context,可以计算出每个单词的摩尔斯编码,到时直接进行匹配即可

因此,定义string codetbl[200]存储字符编码表,其中code[ch]表示字符ch对应的编码串。

定义map<string, vector<string> > ctxt;,其中ctxt[s]表示摩尔斯编码串s对应的可能单词,单词在vector中按输入顺序存放,若改为set,则按字典序排列

接着依次输入摩尔斯密码,根据解码规则处理即可。

注意点

  • 题意不明,经测试,多个精确匹配可输出字典序最小/context中最前面的
  • 模糊匹配一定存在,因为题目仅考虑在字符串末尾增加或减少若干个字符

AC代码(C++11,解密模拟,逆向思维,map)

#include<bits/stdc++.h>
using namespace std;
string codetbl[200], code, s;
char ch;
// map<string, set<string> > ctxt; // 上下文,字典序排列
map<string, vector<string> > ctxt; // 上下文,输入顺序排列
int main() {
    while (cin >>ch && ch != '*') {
        cin >>code; codetbl[ch] = code;
    }
    while (cin >>s && s != "*") {
        string st;
        for (auto c : s) st += codetbl[c];
        // ctxt[st].insert(s); // 字典序排列
        ctxt[st].push_back(s);
    }
    while (cin >>s && s != "*") {
        if (ctxt.find(s) != ctxt.end()) { // 存在
            cout <<*ctxt[s].begin();
            if (ctxt[s].size() > 1) cout <<"!";
        }
        else { // 不存在
            int minlen = 0x3ffff; string ans;
            for (auto p : ctxt) {
                if (s == p.first.substr(0,s.size()) || p.first == s.substr(0,p.first.size())) { // 前缀
                    int i = abs((long)p.first.size()-(long)s.size()); 
                    if (minlen >= i) {
                        minlen = i;
                        ans = *p.second.begin();
                    }
                }
            }
            cout <<ans<<"?";
        }
        puts("");
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值