У меня есть текстовый файл, и я думаю, что я правильно реализовал алгоритм LZW, но сжатый файл становится больше, чем оригинал.
Я не запускаю LZW в байтах текста, а в строке.
Я строю словарь [string:int]
и запустить его. Интересно, должен ли я сделать это с байтами вместо строк?
Он также запускает строку за строкой файла вместо создания всего одного словаря для всего файла.
Это мой LZW
map<string, int> D; //dictionary
int init(){ //init dictionary with all single chars
D.clear(); rD.clear();
f(i,,256){
D[string(1, char(i))] = i + 1;
}
return 257;
}
void encode(char* file){ //LZW encoding method
ifstream in(file);
if (!in.is_open()) {cout<<"Could not open file"<<endl; return;}
else {
ofstream out("compressed.txt");
for(string text; getline(in, text); ){
int value = init();
vector<int> idx;
string p = "", c = "", pc = "";
for(int i = 0; i < text.size(); i++){
c = text[i];
let s = p + c;
if(D.find(s) != D.end()){
p = p + c;}
else{
idx.push_back(D[p]);
D[s] = value++;
p = c;
}
}
idx.push_back(D[p]);
int len = idx.size();
f(i,,len) {out<<idx[i]; if(i == len-1) out<<" 0"<<endl; else out<<" ";}
}
in.close();
out.close();
cout<<"File compressed successfully"<<endl;
}
}
он просто получает адрес файла и сжимает его в файл «compress.txt».
Сердцем LZW является преобразование дублированных байтов в символ, а затем запись символов в битовый поток. Чем больше у вас дублированных байтов, тем выше степень сжатия. А упакованные биты сэкономят много места.
Когда вы пишете символ как int для ofstream таким образом, он может использовать более 4 байтов. Но с упакованным битом он должен занимать от 9 до 16 бит в зависимости от того, как вы его установили. Я думаю, что это главная причина, по которой ваш результат превосходит ожидания.
Удачи.
Других решений пока нет …