По сути, я пытаюсь создать базовую систему счисления 62 в C ++ (буквенно-цифровая система счисления, включающая a-z, A-Z и 0-9). Как бы что-то подобное произошло? Я попытался использовать массив символов следующим образом:
const char alphaNum[62] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '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', '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' };
однако написание функций для использования этого массива и попытки подсчета требует слишком много кода, чтобы быть практичным (для 0–61, конечно, просто выберите его из массива. Проблема возникает, когда вы пытаетесь сделать многозначные числа, то есть 00) , Было бы гораздо проще просто сказать foobar++;
, У кого-нибудь есть способ определить системы счисления или, по крайней мере, для меня способ сделать так, чтобы мне не приходилось писать регистр каждый раз, когда он достигает Z?
РЕДАКТИРОВАТЬ: это должно быть const char, не знаю, почему В.С. решил, что было бы весело не копировать некоторые из них.
Следующее может помочь: (http://ideone.com/y1gZDF)
(Вы можете изменить внутреннее представление в соответствии с вашими Большое количество).
class N62
{
public:
explicit N62(const std::string& digits) : N62(digits.c_str(), digits.size()) {}
N62(const char* digits, std::size_t len) : value(0u)
{
for (std::size_t i = 0; i != len; ++i) {
auto pos = std::find(std::begin(base), std::end(base), digits[i]);
if (pos == std::end(base)) {
throw std::runtime_error("incorrect digit");
}
value *= 62;
value += pos - std::begin(base);
}
}
N62(std::size_t value) : value(value) {}
operator std::size_t () const { return value; }
std::string str() const
{
if (value == 0u) {
return "0";
}
std::string res;
for (std::size_t n = value; n != 0; n /= 62) {
res.push_back(base[n % 62]);
}
std::reverse(res.begin(), res.end());
return res;
}
private:
std::size_t value;
private:
static constexpr char base[] =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
};
Кроме того, вы можете добавить строковый литерал пользователя следующим образом:
N62 operator "" _n62 (const char *t, std::size_t len)
{
return N62(t, len);
}
И используйте это так: "1Z"_n62
(которые решают в 123
в десятичном виде).
Вам необходимо разделить внешнее (для пользователя) представление и внутреннее представление.
Внутреннее Представительство
Внутри компьютера вы должны использовать наиболее эффективное представление. Это может быть шестнадцатеричное, двоичное или десятичное число; или не беспокойся об этом.
При представлении Пользователю вы должны использовать Внешнее Представление.
Внешнее Представительство
Ваш массив символов представляет цифры вашей системы счисления. (Это также должно быть const
.) Вы должны изолировать цифры от вашего внутреннего представления. Например, в базе 16 мы делим число на 16, чтобы сместить число вправо, и используем по модулю разделение, чтобы получить остаток. Остальная часть — это цифра. Используйте остаток, чтобы найти представление цифр из вашего массива.
Попробуйте свои алгоритмы на меньшей числовой основе, такой как 17 или 18. Расширение до базы 62 должно быть вопросом изменения #define
или же const integer
,
Редактировать 1: сложный метод
Более сложный метод — использовать один байт для каждой цифры вашей системы счисления. Байт, октет или беззнаковый символ имеет диапазон от 0 до 255, поэтому должен содержать цифру от основания 62.
Использовать std::vector<unsigned char>
представлять ваш номер. Вам нужно будет решить, находится ли самая значимая цифра в начале вектора или в конце.
Чтобы увеличить цифру:
add 1 to digit.
if digit value > 62
{
set digit to zero.
Load digit with next greater column value (i.e. vector[position + 1];
Repeat at top of algorithm
}
Это стандартный алгоритм независимо от базы (10, 8, 16 и т. Д.).
Основные правила десятичного сложения, вычитания, умножения и деления все еще применяются. (Подсказка).
Это техника, используемая в Большое количество библиотеки.
Только системы счисления представления чисел. Числа не против того, как мы их пишем. Итак, наши проблемы:
Как использовать base62 для объявления чисел в тексте программы?
Вы должны объявить, как вы помечаете номера base62. Префикс «0x» и «$» зарезервирован для base16, префикс «0» зарезервирован в восьмеричном формате, префикс «%» для двоичного файла, «*» используется по нескольким причинам, возможно, тильда — это ваш префикс, пример: ~ Uu3n
Затем вы должны написать препроцессор, который преобразует ваши числа base62 в десятичный (или шестнадцатеричный, как вы хотите) формат.
Как вывести числа в base62?
Это сложнее. Вы должны преобразовать все выходные данные в base62. Так
printf("%d in base62 is %D \n",value,value);
должен быть преобразован в
printf("%d in base62 is %s \n",value,tob64(value));
Не слишком элегантно
Может быть, класс-обертка должен быть лучше (как целое число на Яве).