I'm currently translating an algorithm in Python to C++.
This line EXCH_SYMBOL_SETS = [["i", "1", "l"], ["s", "5"], ["b", "8"], ["m", "n"]]
is now
vector<vector<char>> exch_symbols;
vector<char> vector_1il;
vector_1il.push_back('1');
vector_1il.push_back('i');
vector_1il.push_back('l');
vector<char> vector_5s;
vector_5s.push_back('5');
vector_5s.push_back('s');
vector<char> vector_8b;
vector_8b.push_back('8');
vector_8b.push_back('b');
vector<char> vector_mn;
vector_mn.push_back('m');
vector_mn.push_back('n');
exch_symbols.push_back(vector_1il);
exch_symbols.push_back(vector_5s);
exch_symbols.push_back(vector_8b);
exch_symbols.push_back(vector_mn);
I hate to have an intermediate named variable for each inner variable in a 2-D vector. I'm not really familiar with multidimensional datastructures in C++. Is there a better way?
What's happening afterwards is this:
multimap<char, char> exch_symbol_map;
/*# Insert all possibilities
for symbol_set in EXCH_SYMBOL_SETS:
for symbol in symbol_set:
for symbol2 in symbol_set:
if symbol != symbol2:
exch_symbol_map[symbol].add(symbol2)*/
void insert_all_exch_pairs(const vector<vector<char>>& exch_symbols) {
for (vector<vector<char>>::const_iterator symsets_it = exch_symbols.begin();
symsets_it != exch_symbols.end(); ++symsets_it) {
for (vector<char>::const_iterator sym1_it = symsets_it->begin();
sym1_it != symsets_it->end(); ++sym1_it) {
for (vector<char>::const_iterator sym2_it = symsets_it->begin();
sym2_it != symsets_it->end(); ++sym2_it) {
if (sym1_it != sym2_it) {
exch_symbol_map.insert(pair<char, char>(*sym1_it, *sym2_it));
}
}
}
}
}
So this algorithm should work in one way or another with the representation here. The goal is that EXCH_SYMBOL_SETS can be easily changed later to include new groups of chars or add new letters to existing groups. Thank you!
I would refactor, instead of vector<char>, use std::string as internal, i.e.
vector<string> exch_symbols;
exch_symbols.push_back("1il");
exch_symbols.push_back("s5");
exch_symbols.push_back("b8");
exch_symbols.push_back("mn");
then change your insert method:
void insert_all_exch_pairs(const vector<string>& exch_symbols)
{
for (vector<string>::const_iterator symsets_it = exch_symbols.begin(); symsets_it != exch_symbols.end(); ++symsets_it)
{
for (string::const_iterator sym1_it = symsets_it->begin(); sym1_it != symsets_it->end(); ++sym1_it)
{
for (string::const_iterator sym2_it = symsets_it->begin(); sym2_it != symsets_it->end(); ++sym2_it)
{
if (sym1_it != sym2_it)
exch_symbol_map.insert(pair<char, char>(*sym1_it, *sym2_it));
}
}
}
}
You could shorten it by getting rid of the intermediate values
vector<vector<char> > exch_symbols(4, vector<char>()); //>> is not valid in C++98 btw.
//exch_symbols[0].reserve(3)
exch_symbols[0].push_back('i');
etc.
You could also use boost.assign or something similiar
EXCH_SYMBOL_SETS = [["i", "1", "l"], ["s", "5"], ["b", "8"], ["m", "n"]] then becomes
vector<vector<char>> exch_symbols(list_of(vector<char>(list_of('i')('1')('l')))(vector<char>(list_of('s')('5'))(list_of('m')('n'))) (not tested and never used it with nested vectors, but it should be something like this)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With