【问题标题】:LZW compression generation file bigger than originalLZW压缩生成文件比原来大
【发布时间】:2016-12-12 00:56:31
【问题描述】:

我有一个文本文件,我认为我正确地实现了 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;

}

}

它只是接收文件的地址并将其压缩为“compressed.txt”文件。

【问题讨论】:

  • 首先你输出的是文本文件,但是你需要一个二进制文件
  • 您能更好地解释二进制文件的含义吗?我该怎么做?它对我有什么帮助?
  • 您需要打开输出文件以进行二进制输出:ofstream out("compressed.txt", std::ios::binary); 。想象一下,您正在尝试编写 . 1234 到一个文件,在文本模式下它需要 4 个字节,但在二进制中它只需要 2 个
  • 它有点帮助,但还不够……将其转换为二进制只是以这种方式更改 ofstream 吗?如果是,还不够,9mb 变成了 16
  • @Daniel out &lt;&lt; ... &lt;&lt; endl; -- 为什么要将行尾字符写入二进制文件?此外,您测试此代码以查看它是否真的有效的方法是获取另一个不是您编写的、有信誉的 lzw 程序,看看它是否可以对您创建的文件进行 lzw 解码。如果它不能这样做或检测到错误,那么您对数据进行编码的代码不正确。

标签: c++ compression lzw


【解决方案1】:

LZW 的核心是将重复的字节转换为符号,然后将符号写入比特流。您拥有的重复字节越多,您获得的压缩率就越高。并且打包的位会节省很多空间。

当您以这种方式将符号作为 int 写入 ofstream 时,它可能使用超过 4 个字节。但是对于打包位,它应该占用 9 位到 16 位,具体取决于您的设置方式。我认为这是您的输出大于预期的主要原因。

祝你好运。

【讨论】:

  • 我为什么要避免这种额外的花费?
  • 你必须打包符号。例如,前 256 个符号使用 9 位,然后接下来的 512 个符号使用 10 位,依此类推。我不记得它是如何组织的,但理解和实现并不难。