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;
}