#c #math
#c #математика
Вопрос:
Каков наилучший способ преобразовать массив символов (содержащий байты из файла) в десятичное представление, чтобы его можно было преобразовать обратно позже?
Например, «test» -> 18951210 -> «test».
ОТРЕДАКТИРОВАНО
Комментарии:
1. 18951210 не является представлением «test»
2. Я знаю, что приводил это как пример того, чего бы я хотел.
Ответ №1:
Это невозможно сделать без класса bignum, поскольку в an возможно больше комбинаций букв, чем целых unsigned long long
. ( unsigned long long
будет содержать около 7-8 символов)
Если у вас есть какой-то класс bignum:
biguint string_to_biguint(const std::stringamp; s) {
biguint result(0);
for(int i=0; i<s.length(); i) {
result *= UCHAR_MAX;
result = (unsigned char)s[i];
}
return resu<
}
std::string biguint_to_string(const biguint u) {
std::string resu<
do {
result.append(u % UCHAR_MAX)
u /= UCHAR_MAX;
} while (u>0);
return resu<
}
Примечание: преобразование строки в uint потеряет начальные нули, а преобразование uint в string потеряет конечные нули.
Комментарии:
1. Спасибо, именно то, что мне было нужно. Кстати, вы, вероятно, забыли изменить вторую функцию на «convert_to_string».
2. ДА. Я сделал старую копию / вставку / забыл изменить.
Ответ №2:
Я не уверен, что именно вы имеете в виду, но символы хранятся в памяти как их «представление», поэтому вам не нужно ничего преобразовывать. Если вы все еще хотите, вы должны быть более конкретными.
РЕДАКТИРОВАТЬ: Вы можете
- Попробуйте прочитать байт за байтом, сдвигая результат на 8 бит влево и заменяя его следующим байтом.
- Попробуйте использовать mpz_inp_raw
Комментарии:
1. Извините, я не очень хорошо это объяснил. Я имею в виду иметь десятичное представление строки.
2. Я думаю, что я почти понимаю. Ну, вы можете посимвольно умножить свой mpz на 256 (или сдвинуть 8 бит, есть что-то вроде _mul_2exp или что-то еще) и добавить следующий символ?
3. Я все еще могу использовать mpz_t, поэтому я попробую это. Вы можете отредактировать свой ответ, и я соглашусь 😉
4. Кроме того, вполне вероятно, что mpz_inp_raw из файла будет делать то, что вы хотите.
5. Сейчас я буду использовать mpz_inp_raw, но «Мычание утки» будет лучше позже. В любом случае спасибо 😉
Ответ №3:
Вы можете использовать дерево, подобное алгоритму сжатия Хаффмана, а затем представить путь в дереве в виде чисел.
Вам придется где-то хранить словарь, но вы можете просто создать постоянный словарь, который охватывает всю таблицу ASCII, поскольку сжатие здесь не является целью.
Ответ №4:
Преобразование не требуется. Вы можете просто использовать указатели.
Пример:
char array[4 * NUMBER];
int *pointer;
Имейте в виду, что «длина» pointer
равна NUMBER
.
Ответ №5:
Как уже упоминалось, символьные строки для начала уже представляют собой диапазоны байтов (и, следовательно, легко отображаются в виде десятичных чисел). Пронумеруйте свои байты от 000 до 255 и соедините их вместе, и вы получите десятичное число, чего бы оно ни стоило. Было бы полезно, если бы вы точно объяснили, почему вы хотели бы использовать десятичные числа, в частности, поскольку шестнадцатеричное значение было бы проще.
Если вас интересует сжатие базовых массивов, формирующих эти числа для строк Unicode, вас может заинтересовать:
http://en.wikipedia.org/wiki/Standard_Compression_Scheme_for_Unicode
Если вы хотите получить некоторые преимущества сжатия, но все еще хотите быстрого чтения с произвольным доступом и записи в «упакованном» количестве, вам может показаться интересной моя библиотека «NSTATE»:
http://hostilefork.com/nstate/
Например, если вам просто нужно представление, содержащее только 26 английских букв…вы могли бы сохранить «test» в:
NstateArray<26> myString (4);
Вы могли бы читать и записывать буквы, не проходя через процесс сжатия или распаковки, в меньшем диапазоне чисел, чем в обычной строке. Работает с любым основанием.
Ответ №6:
Предполагая, что вы хотите сохранить целые числа(Я читаю как ascii-коды) в строке. Это добавит начальные нули, которые вам понадобятся, чтобы вернуть его в исходную строку. символ — это байт с максимальным значением 255, поэтому для него потребуется три цифры в числовой форме. Это также довольно легко можно сделать без STL. Но почему бы не использовать имеющиеся у вас инструменты?
#include <iostream>
#include <sstream>
using namespace std;
char array[] = "test";
int main()
{
stringstream out;
string s=array;
out.fill('0');
out.width(3);
for (int i = 0; i < s.size(); i)
{
out << (int)s[i];
}
cout << s << " -> " << out.str();
return 0;
}
вывод:
test -> 116101115116
Добавлено:
измените строку на
out << (int)s[i] << ",";
вывод
test -> 116,101,115,116,
Комментарии:
1. Это просто добавление значения каждого символа к строке, поэтому я не могу знать, является ли это 116,101,115,116 или 11,61,011,15,116…
2. Каждый ascii-код для символа имеет длину ровно 3 цифры (дополняется нулями), при желании можно легко добавить запятую.
out << (int)s[i] << ",";
и избавьтесь отout.width(3)
, если вы не хотите, чтобы их всех было 3. Наиболее читаемых символов в любом случае будет 3. займет меньше места, чем запятые, чтобы просто предположить, что все будет три.