Secret decoder

Your task is to decode messages that were encoded with substitution ciphers. In a substitution cipher, all occurrences of a character are replaced by a different character. For example, in a cipher that replaces "a" with "d" and "b" with "e", the message "abb" is encoded as "dee".

The exact character mappings that are used in the substitution ciphers will not be known to you. However, the dictionary of words that were used will be given. You will be given multiple encoded messages to decode (one per line) and they may use different substitution ciphers. The same substitution cipher is used on all of the words in a particular message.

For each scrambled message in the input, your program should output a line with the input line, followed by the string " = " (without the quotes), followed by the decoded message.

NOTE: All inputs are from stdin and output to stdout. The input will be exactly like how it's given in the problem and

your output should exactly match the given example output

Example:

input file:

//dict 

hello 

there 

yello 

thorns

 //secret 

12334 51272 

12334 514678

output: 12334 51272 = hello there 

12334 514678 = hello thorns


brute-force,方法类似于sudoku,但是需要两个map同时记录双向的映射,关键是看题看了好久。。。

#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <stdlib.h>
#include <map>
#include <deque>

using namespace std;

void split_stream(istream& is, vector<string>& params, char dm)
{
    string s;
    params.clear();
    while (getline(is, s, dm)) {
        params.push_back(s);
    }
}

bool check(map<char, char> &translation, map<char, char> &reverse, string secret, string dict) {
    for (size_t j = 0; j < secret.size(); ++j) {
         map<char, char>::iterator mit = translation.find(secret[j]);
         map<char, char>::iterator rit = reverse.find(dict[j]);
         if ((mit != translation.end() && mit->second != dict[j]) ||( rit!=reverse.end() && rit->second!=secret[j] )) {
         // contradict, try next dict word
            return false;
         }
         translation[secret[j]] = dict[j];
         reverse[dict[j]] = secret[j];
    }
    return true;
}

bool find_substitution(const vector<string>& secret, const vector<string>& dict, size_t i, map<char, char> translation,  map<char, char> reverse, deque<string>& message)
{
    if (i >= secret.size()) {
        // all words are translated
        return true;
    }

    map<char, char> trans_backup = translation;
    map<char, char> rev_backup=reverse;
    for (vector<string>::const_iterator it = dict.begin(); it != dict.end(); ++it) {
        if (secret[i].size() == it->size()) {
            if (check(translation, reverse, secret[i], (*it))) {
                if (find_substitution(secret, dict, i + 1, translation, reverse, message)) {
                    message.push_front(*it);
                    return true;
                }
            }
    		translation = trans_backup;
    		reverse = rev_backup;
        }
        
    }
    return false;
}

void decode(const vector<string>& secret,   
            const vector<string>& dict,   
            deque<string>& message)  
{  
    map<char, char> translation; 
    map<char, char> reverse;
    if (find_substitution(secret, dict, 0, translation, reverse, message)) {  
        for (size_t i = 0; i < secret.size(); ++i) {  
            cout << secret[i] << " ";  
        }  
        cout << "=";  
        for (size_t i = 0; i < message.size(); ++i) {  
            cout << " " << message[i];  
        }  
        cout << endl;  
    }  
}  

int main(int argc, char** argv)
{
    vector<string> inputs, dict, secret, cur;
    vector<int> secretNum;
    deque<string> message;
    split_stream(cin, inputs, '\n');
    vector<string>::iterator it = inputs.begin();

    // get the dict
    if (*it == "//dict") {
        ++ it;
        while (it != inputs.end() && *it != "//secret") {
            dict.push_back(*it);
            ++ it;
        }
    }

	if (it != inputs.end() && *it == "//secret") {
        ++ it;
        while (it != inputs.end() && *it != "//secret") {
            message.clear();
            stringstream ss(*it);
            split_stream(ss, secret, ' ');
            ++ it;
            decode(secret, dict, message);
        }
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值