簡體   English   中英

如何讀取二進制文件來計算霍夫曼樹的頻率?

[英]How to read a binary file to calculate frequency of Huffman tree?

我必須從“二進制文件”中計算霍夫曼樹的頻率作為唯一參數。 我懷疑二進制文件是僅包含“0”和“1”的文件。

而頻率是字母數量的重復(例如,abbacdd,其中a = 2的頻率,b = 2,c = 1,d = 2)。 我的結構必須是這樣的:

struct Node
{
unsigned char symbol;   /* the symbol or alphabets */
int freq;               /* related frequency */
struct Node *left,*right; /* Left and right leafs */
};

但我根本不明白如何從“.bin”文件(僅包含“0”和“1”)獲取符號?

當我嘗試查看文件的內容時,我得到:

hp@ubuntu:~/Desktop/Internship_Xav/Huf_pointer$ xxd -b out.bin 
0000000: 00000000 00000000 00000000 00000000 00000000 00000000  ......
0000006: 00000000 00000000 00000000 00000000 00000000 00000000  ......
000000c: 00000000 00000000 00000000 00000000 00000000 00000000  ......
0000012: 00000000 00000000 00000000 00000000 00000000 00000000  ......
0000018: 00000000 00000000 00000000 00000000 00000000 00000000  ......
000001e: 00000000 00000000 00000000 00000000 00000000 00000000  ......
0000024: 00000000 00000000 00000000 00000000 00000000 00000000  ......
000002a: 00000000 00000000 00000000 00000000 00000000 00000000  ......
0000030: 00000000 00000000 00000000 00000000 00000000 00000000  ......
.........//Here also there is similar kind of data    ................
00008ca: 00010011 00010011 00010011 00010011 00010011 00010011  ......
00008d0: 00010011 00010011 00010011 00010011 00010011 00010011  ......
00008d6: 00010011 00010011 00010011 00010011 00010011 00010011  ..... 

所以, 我根本不了解頻率在哪里以及符號在哪里。 如何存儲符號以及如何計算頻率。 實際上,在有頻率和符號之后,我將使用它創建HUffman樹。

首先,您需要創建某種頻率表。
你可以使用std::map
你會做這樣的事情:

#include <algorithm>
#include <fstream>
#include <map>
#include <string>

std::map <unsigned char, int> CreateFrequencyTable (const std::string &strFile)
{
    std::map <unsigned char, int> char_freqs ; // character frequencies

    std::ifstream file (strFile) ;

    int next = 0 ;
    while ((next = file.get ()) != EOF) {
        unsigned char uc = static_cast <unsigned char> (next) ;

        std::map <unsigned char, int>::iterator iter ;
        iter = char_freqs.find (uc) ;

        // This character is in our map.
        if (iter != char_freqs.end ()) {
            iter->second += 1 ;
        }

        // This character is not in our map yet.
        else {
            char_freqs [uc] = 1 ;
        }
    }

    return char_freqs ;
}

然后你可以像這樣使用這個函數:

std::map <unsigned char, int> char_freqs = CreateFrequencyTable ("file") ;

您可以獲得頻率最高的元素,如下所示:

std::map <unsigned char, int>::iterator iter = std::max_element (
    char_freqs.begin (), 
    char_freqs.end (), 
    std::map <unsigned char, int>::value_comp
) ;

然后你需要建立你的霍夫曼樹。
請記住,字符都是葉節點,因此您需要一種方法來區分葉節點和非葉節點。

更新

如果從文件中讀取單個字符太慢,您可以始終將所有內容加載到這樣的向量中:

// Make sure to #include <iterator>
std::ifstream file ("test.txt") ;
std::istream_iterator <unsigned char> begin = file ;
std::vector<unsigned char> vecBuffer (begin, std::istream_iterator <unsigned char> ()) ;

您仍然需要創建頻率表。

霍夫曼樹中的符號可以是任何東西,
但是你必須為每個符號使用一個unsigned char
你應該拿一個字節?
所以不,不僅是0或1,而是八次0或1。

就像輸出xxd某處的00010011一樣
xxd -b將為每個字節提供8個0/1。
你也可以寫一個0到255之間的數字,
或兩次一個字符0123456789abcdef
如何在屏幕上顯示一個字節有很多可能性,
但這根本不重要。

如果您知道如何在C / C ++中讀取文件的內容,
只需讀取unsigned char直到文件結束
並計算那里的值是多少。 就這樣。

因為您可能在程序代碼中寫入十進制數字,
有256個不同的值(0,1,2 ... 255)。
所以你需要256個整數(在一個數組中,或你的Node結構......)
計算每個值出現的頻率。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM