Краткие списки / векторы в C ++ - PullRequest
3 голосов
/ 05 января 2011

В настоящее время я перевожу алгоритм на Python на C ++.

Эта строка EXCH_SYMBOL_SETS = [["i", "1", "l"], ["s", "5"], ["b", "8"], ["m", "n"]] теперь

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

Я не хочу иметь промежуточную именованную переменную для каждой внутренней переменной вдвумерный вектор.Я не очень знаком с многомерными структурами данных в C ++.Есть ли лучший способ?

После этого происходит следующее:

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

Так что этот алгоритм должен так или иначе работать с представлением здесь.Цель состоит в том, чтобы EXCH_SYMBOL_SETS можно было легко изменить позже, чтобы включить новые группы char s или добавить новые буквы в существующие группы.Спасибо!

Ответы [ 5 ]

2 голосов
/ 05 января 2011

Я бы рефакторил, вместо vector<char>, использовал бы std::string как внутренний, т.е.

vector<string> exch_symbols;
exch_symbols.push_back("1il");
exch_symbols.push_back("s5");
exch_symbols.push_back("b8");
exch_symbols.push_back("mn");

, затем изменил бы ваш метод вставки:

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));
      }
    }
  }
}
1 голос
/ 05 января 2011

В c ++ 0x инструкция
vector<string> EXCH_SYMBOL_SETS={"i1l", "s5", "b8", "mn"} ;
компилируется и работает нормально. К сожалению, достаточно похожее утверждение
vector<vector<char>> EXCH_SYMBOL_SETS={{'i','1','l'},{'s','5'}, {'b','8'}, {'m','n'}};
не работает :-(.

Это реализовано в g ++ 4.5.0 или более поздней версии, вам следует добавить параметр -std=c++0x. Я думаю, что эта функция еще не доступна в Microsoft C (VC10), и я не знаю, каково состояние других компиляторов.

1 голос
/ 05 января 2011

На ваш реальный вопрос ...

как я мог перевести L = [A, [B], [[C], D]]] на C ++ ... вообще!

Прямого перевода нет - вы переключились с хранения значений одного типа на хранение значений переменных типа. Python допускает это, потому что это язык с динамической типизацией, а не потому, что он имеет лучший синтаксис массива.

Есть способы реплицировать поведение в C ++ (например, вектор boost :: any или boost :: variable или пользовательский контейнерный класс, который поддерживает этот behviour), но это никогда не будет таким простым, как это в Python.

1 голос
/ 05 января 2011

Ваш код:

    vector<char> vector_1il;
    vector_1il.push_back('1');
    vector_1il.push_back('i');
    vector_1il.push_back('l');

Краткий код:

char values[] = "1il";
vector<char> vector_1il(&values[0], &values[3]);

С вами все в порядке?


Если вы хотите использовать std::stringкак подсказывает Ним , тогда вы можете использовать даже это:

//Concise form of what Nim suggested!
std::string s[] = {"1il", "5s", "8b", "mn"};
vector<std::string> exch_symbols(&s[0], &s[4]);

Остальные вы можете следить за постом Нима .: -)

1 голос
/ 05 января 2011

Вы можете сократить его, избавившись от промежуточных значений

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.

Вы также можете использовать boost.assign или что-то похожее
EXCH_SYMBOL_SETS = [["i", "1", "l"], ["s", "5"], ["b", "8"], ["m", "n"]], затем оно становится vector<vector<char>> exch_symbols(list_of(vector<char>(list_of('i')('1')('l')))(vector<char>(list_of('s')('5'))(list_of('m')('n'))) (не проверено и никогда не использовалосьэто с вложенными векторами, но должно быть что-то вроде этого)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...