Я пытаюсь определить две неупорядоченные карты на глобальном уровне, я определяю их с помощью циклов, и я не хочу помещать циклы в main().
В частности, я пытаюсь определить алфавит base-36, я использую арабские цифры для цифр 0-9, затем базовый латинский алфавит для цифр 10-35, одна карта предназначена для преобразования строки в целое число, и она должна поддерживать верхний и нижний регистр, другой для преобразования целого числа в его строковое представление в заданной базе, и оно должно быть только в нижнем регистре.
Вот мой код, очевидно, он не работает:
#include <unordered_map>
using namespace std;
const unordered_map<string, int> digits;
const unordered_map<int, string> alphabet;
for (int i = 0; i < 10; i++) {
string d = char(i + 48);
digits[d] = i;
alphabet[i] = d;
}
for (int i = 10; i < 36; i++) {
string upper = char(i + 55);
string lower = char(i + 87);
digits[upper] = i;
digits[lower] = i;
alphabet[i] = lower;
}
Я знаю, что если я поставлю циклы внутри функции main(), это должно сработать. Но я не хочу этого делать.
Есть ли способ инициализировать их напрямую и использовать оператор присваивания для их определения, возможно, с пониманием?
Что-то вроде следующего кода Python:
DIGITS = {
**{chr(i + 48): i for i in range(10)},
**{chr(i + j): i for i in range(10, 36) for j in (55, 87)},
}
ALPHABET = {
**{i: chr(i + 48) for i in range(10)},
**{i: chr(i + 87) for i in range(10, 36)},
}
Несколько неактуально, но вот моя текущая работающая программа, которая преобразует строки в числа и наоборот, я пытаюсь избавиться от операторов if внутри функций преобразования.
И я хочу использовать unordered_map здесь, чтобы ознакомиться с ним, а также сравнить и сопоставить его с Python dict.
То, что вы хотите сделать, чтобы использовать циклы и вычисления, чтобы инициализировать переменные, должно быть сделано в функции main. Или создайте класс или структуру для решения проблемы и используйте его конструктор для инициализации.
С другой стороны, пожалуйста, не используйте магические числа так, как вы это делаете. Если вы хотите перейти от '0' к '9', используйте эти значения. А затем вычтите '0', чтобы получить фактическое целочисленное значение. И я рекомендую вам сделать digit карту из символов в целочисленное значение. И учитывая простую арифметику, необходимую для преобразования цифрового символа в его целое значение или наоборот, для чего на самом деле нужны карты? Каков вариант использования этих карт? Какую реальную проблему должны решить эти карты?
Да, и простая арифметика для цифр гарантируется только спецификацией C++ для цифр. Ваши прописные/строчные буквы не всегда будут работать везде.
Вы используете std::string и неупорядоченную карту для преобразования символов в числа и наоборот? Просто напишите простую функцию с несколькими ifs — так будет эффективнее. Максимум используйте std::array, чтобы заменить пару ifs.





Используйте непосредственно вызываемое лямбда-выражение для инициализации вашей переменной.
#include <unordered_map>
#include <string>
#include <iostream>
// using namespace std; <== do not do this
const auto digits = []
{
std::unordered_map<std::string, int> digits;
for (int i = 0; i < 10; i++)
{
digits.insert({ std::to_string(i), i });
}
return digits;
}(); // make a lambda expression and immediately invoke it.
int main()
{
// use a range-based for loop + structured binding
// to show content of the map
for (const auto& [key, value] : digits)
{
std::cout << "[" << key << ", " << value << "]\n";
}
return 0;
}
Он мог бы также написать функцию вместо лямбды. То же самое.
@ ALX23z Возможно, но тогда функция будет доступна для использования и в остальной части кода (таким образом, ее можно использовать только для инициализации). Это также весьма полезно для инициализации constexpr (что выходит за рамки текущего вопроса).
В целом я бы сказал, что нет. С глобальными переменными в больших проектах сложно иметь дело. Но в этом случае вы можете переместить код инициализации в лямбда-выражение, которое вернет инициализированную карту.