实施霍夫曼树

时间:2019-03-07 18:55:04

标签: c++ data-structures visual-studio-2017

我有一个程序,该程序根据在文本输入文件中读取的ASCII字符频率生成霍夫曼树。霍夫曼码存储在由256个元素组成的字符串数组中;如果未读取字符,则为空字符串。

我现在正在尝试通过编写一个函数来实现霍夫曼树,该函数接受存储在字符串数组中的霍夫曼代码,并将输入文件的编码输出到输出文件中。

我很快意识到,我目前的做法违反了任务的含义。我只是尝试将代码字符串复制到输出文件中,以使编码后的输出文件大于输入文件。

我希望获得有关更改当前功能的帮助,以便它可以将位输出到输出文件中,从而使输出文件小于输入文件。我被卡住是因为我目前仅读写字节?

我当前的功能(fileName是输入文件参数,fileName2是输出文件参数):

void encodeOutput(const string & fileName, const string & fileName2, string code[256]) {
    ifstream ifile;//to read file
    ifile.open(fileName, ios::binary);
    if (!ifile)//to check if file is open or not
    {
        die("Can't read again"); // function that exits program if can't open
    }
    ofstream ofile; 
    ofile.open(fileName2, ios::binary); 
    if (!ofile) {
        die("Can't open encoding output file"); 
    }
    int read;
    read = ifile.get();//read one char from file and store it in int
    while (read != -1) {//run this loop until reached to end of file(-1)
        ofile << code[read]; //put huffman code of character into output file
        read = ifile.get();//read next character
    }
    ifile.close();
    ofile.close();
}

1 个答案:

答案 0 :(得分:1)

如果您需要写{em> bits ,则不能仅仅使用ofile << code[read];ofstream可以理解的最小单位是一个字节。

要克服这一点,您可以将您的位写入某种“位缓冲区”(char即可),并在具有8位后将 写出。我不十分清楚您的代码字符串的样子,但这应该可以做到:

char buffer = 0, bit_count = 0;
while (read != -1) {
  for (int b = 0; b < code[read].size(); b++) {
    buffer << 1;
    buffer |= code[read][b] != 0;
    bit_count++;
    if (bit_count == 8) {
      ofile << buffer;
      buffer = 0;
      bit_count = 0;
    }
  }
  read = ifile.get();
}

if (bit_count != 0)
  ofile << (buffer << (8 - bit_count));