Какая C ++ лучшая альтернатива словарю Python и zip?

Какая C ++ лучшая альтернатива dict (zip (values ​​…)) в python?

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

Код выглядит следующим образом (я изменил имена переменных и немного обобщил их, но это та же идея):

(dict(zip(wordCollection, [word.strip() for word in currentLine.split(',')][1:-1])))

Я заменил раздетые и разбитые слова на обрезанный токенизированный вектор, используя boost, и это прекрасно работает; однако я потерпел неудачу, пытаясь найти лучший способ перевести комбинацию dict / zip.

1

Решение

Вы действительно не должны пытаться переводить идиомы напрямую с одного языка на другой.

В C ++ вы обычно не пишете функции, которые принимают итераторы и генерируют новые итераторы; вместо этого вы пишете функции, которые принимают итераторы ввода и вывода и копируют из одного в другое. Итак, вы могли бы написать zip функция, принимающая входной итератор Tвходной итератор Uи выходной итератор над pair<T, U>,

Но тогда вы не собираетесь связывать два вызова таким образом, потому что ваш zip функция не собирается возвращать что-либо (например, диапазон итераторов), которое можно было бы с пользой передать любому виду dict функция. Вместо этого вы можете создать dict аналог unordered_map), создайте в нем выходной итератор и используйте zip функция для копирования пар в него.

Что-то вроде этого:

template <I1, I2, O>
void zip(I1 it1, I1 it1end, I2 it2, I2 it2end, O o) {
while ((it1 != it1end) && (it2 != it2end)) {
*o++ = std::make_pair(*it1++, *it2++);
}
}

std::unordered_map<T, U> mapping;
zip(c1.begin(), c1.end(), c2.begin(), c2.end(), std::inserter(mapping, mapping.end()));

Кроме я не думаю, что вы можете использовать inserter на unordered_map так или нет, так что вы должны написать map_inserter функция вместо

Если вы не знаете, типы T а также U локально вы можете обернуть все это в шаблон функции, который извлекает типы из типов элементов итераторов, чтобы вы могли auto Это. (В C ++ 11 вы можете decltype это без необходимости функции, но выражение будет беспорядок.)


Если у вас есть несколько вариантов использования zip а также map_inserter, может быть, стоит написать их. Но в противном случае лучшим решением было бы развернуть его в явный цикл:

auto it1 = c1.begin(), it1end = c1.end(), it2 = c2.begin(), it2end = c2.end();
std::unordered_map<T, U> mapping;
while ((it1 != it1end) && (it2 != it2end)) {
mapping[*it1++] = *it2++;
}
2

Другие решения

Хорошо, когда у вас есть такие векторы, как:

std::vector<std::string> wordCollection;
std::vector<std::string> splitWords;

тогда вы можете просто повторить:

std::map<std::string, std::string> dict; // or std::unordered_map
std::size_t minSize = std::min(wordCollection.size(), splitWords.size());
for (size_t i = 0; i != minSize; ++i) {
dict.insert(std::make_pair(wordCollection[i], splitWords[i]));
}
4

ИМО, лучшая альтернатива С ++ для dict является std::unordered_map, который является хеш-таблицей, и для zip, его ranges::view::zip от D4128 предложение по диапазонам, для которого справочная реализация может быть доступна в github.com/ericniebler/range-v3.

Код C ++ 11:

#include <string>
#include <vector>
#include <unordered_map>
#include <range/v3/view/zip.hpp>

int main() {
using namespace std;
using ranges::view::zip;

int ints[] = {1, 2, 3};
vector<string> strings = {"a", "b"};
unordered_map<int, string> dict(zip(ints, strings));
}

Я надеюсь, что это станет стандартом C ++ в будущем.

1

dict(zip(labels,values))  --->  dict([("a",1),("b",0)]) ---> dict(a=1,b=0)

dict — это просто хеш-таблица … и это просто создание хеш-таблицы меток и значений, где метки (или ключи) wordCollection и токенизированная строка является значениями

так что, вероятно, хеш-таблица … хотя, вероятно, потребуется больше одной строки, чтобы сделать это в C ++

0
По вопросам рекламы [email protected]