Morse encoder decoder:
#include <unordered_map>
#include <string_view>
#define Sv std::string_view
static const auto [encodeMap, decodeMap] = []{
struct {
std::unordered_map<char, Sv> encode;
std::unordered_map<Sv, char> decode;
} result;
struct {Sv k; char v;} a[] = {
{".-",'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'},
{".----",'1'},
{"..---",'2'},
{"...--",'3'},
{"....-",'4'},
{".....",'5'},
{"-....",'6'},
{"--...",'7'},
{"---..",'8'},
{"----.",'9'},
{"-----",'0'},
};
for (const auto& i : a)
result.encode[i.v] = i.k,
result.decode[i.k] = i.v;
return result;
}();
#include <string>
#define S std::string
static S encode(const Sv str) {
S o;
for (const auto c : str) {
const auto it = encodeMap.find(c | (c <= 'Z') << 5);
if (it == encodeMap.end()) {
if (c <= ' ' && !o.empty()) o += " /";
continue;
}
if (!o.empty()) o += ' ';
o += it->second;
}
return o;
}
static S decode(const Sv str) {
S o;
const auto end = str.end();
for (auto it = str.begin(), start = end;; ++it) {
if (it != end) {
if (*it == '.' || *it == '-') {
if (start == end) start = it;
continue;
}
if (*it == '/') o += ' ';
if (start == end) continue;
}
const auto mit = decodeMap.find({start, it});
if (mit != decodeMap.end()) o += mit->second;
if (it == end) break;
start = end;
}
return o;
}
#include <iostream>
int main() {
for (S s; std::getline(std::cin, s);
std::cout << s << '\n' <<
encode(s) << '\n' <<
decode(encode(s)) << '\n'
);
}