100 бед - 1 ресет
Я реализую алгоритм Хаффмана в Си, т.е. каждый символ (8 бит) заменяю на более короткие коды и записываю в файл. Допустим, я вычислил какой символ на какой код буду заменять, у меня вышло:
H - 0
E - 111
F - 11000
B - 11001
и т.д.
Эта таблица хранится в структуре, где есть сам символ, его заменяющий код и длина этого кода.
Теперь, если закодировать строку HEFB, то как можно соответствующий код записать в новый файл, учитывая то, что 1 символ - 8 бит, а у меня, к примеру, H - всего 1 бит.
H - 0
E - 111
F - 11000
B - 11001
и т.д.
Эта таблица хранится в структуре, где есть сам символ, его заменяющий код и длина этого кода.
Теперь, если закодировать строку HEFB, то как можно соответствующий код записать в новый файл, учитывая то, что 1 символ - 8 бит, а у меня, к примеру, H - всего 1 бит.
Если что не понятно, спрашивайте.
Да! Это далеко не самый оптимальный вариант.
Да! И ещё! Си я не знаю.
Спасибо и за такой вариант.
Так, вопрос, если кодирую двоичный файл, где присутствуют все 256 символов из ASCII, у меня длина кода каждого заменяемого симола равна 8 бит, т.е. другими словами, файл сжать нельзя.. Правильно ли я делаю?
E - 00000111
H - 00000000
и т.д.
С битами работай: пичкай результирующие коды шифтом.
Приведенный выше код, как раз это и делает, но как хорошо он это делает судить не берусь (Си я знаю, но мне невообразимо влом читать на нем во время отпуска)
Так, вопрос, если кодирую двоичный файл, где присутствуют все 256 символов из ASCII, у меня длина кода каждого заменяемого симола равна 8 бит, т.е. другими словами, файл сжать нельзя.. Правильно ли я делаю?
Да, нельзя. Подумай, к примеру, почему нельзя сжать уже сжатый файл?
Vj_o-oy
Ничто не мешает, но цель алгоритма – сжать информацию. Теперь делай вывод – стоит ли «догонять нулями» уже сжатое до прежних размеров?...
{
private:
char *mStream;
uint cBitPos;
public:
BitStream(void *Stream)
{
mStream=(char*)Stream;
cBitPos=0;
};
inline uint GetPos(){ return cBitPos%8?cBitPos/8+1:cBitPos/8; };
inline void SetVal(uint Val, uint n)
{
uint cBit=cBitPos%8;
uint *cSeg=(uint*)&mStream[cBitPos/8];
*cSeg|=Val<<cBit;
cBitPos+=n;
};
inline void GetVal(uint &Val, uint n)
{
uint cBit=cBitPos%8;
uint *cSeg=(uint*)&mStream[cBitPos/8];
Val=((*cSeg)>>cBit)&((1<<n)-1);
cBitPos+=n;
};
};
// C++, но на C переделать недолго
// Val - значние
// n - кол-во бит в значении, максимум 16
// перед записью mStream иницеализировать нулями
// потом функцией fwrite сбрасываем весь поток
// при чтении, выделяем память под поток, функцией fread читаем весь файл или кусок
// по битику через GetVal дастаём значение