Huffman Code

运行标准:C++11

#include<bits/stdc++.h>
#define BinFile "Binfile.bin"
#define TestFile "TestFile.txt"
using namespace std;
typedef struct node{
	char key = '\0';
	int Weight = 0;
	struct node *Leftnode = nullptr;
	struct node *Rightnode = nullptr;
}Treenode;
Treenode *root;
struct cmp1{
    bool operator() (const Treenode &a, const Treenode &b) const
    {
        return a.Weight < b.Weight;
    }
};
/*bool operator<(node a, node b)
{
    a.Weight < b.Weight;
}*/
void TreenodeTransmit(Treenode *a, Treenode *b)
{
    a->key = b->key;
    a->Weight = b->Weight;
    a->Leftnode = b->Leftnode;
    a->Rightnode = b->Rightnode;
}
void BuildHuffmanTree(map<char, int> d)
{
    priority_queue<Treenode, vector<Treenode>, cmp1> T;
    for(auto it : d)
    {
        Treenode *temp = nullptr;
        temp->key = it.first;
        temp->Weight = it.second;
        T.push(*temp);
    }
    if(T.size() == 1)
    {
        Treenode *temp1 = nullptr;
        Treenode *temp2 = nullptr;
        Treenode *top = nullptr;
        *top = T.top();
        TreenodeTransmit(temp2, top);
        T.pop();
        temp1->key = temp2->key, temp1->Weight = temp2->Weight;
        temp1->Leftnode = temp2;
        temp1->Rightnode = nullptr;
        T.push(*temp1);
    }
    else{
        while(T.size() != 1)
        {
            Treenode *temp3 = nullptr;
            Treenode *temp4 = nullptr;
            Treenode *Newnode = nullptr;
            Treenode *top = nullptr;
            *top = T.top();
            TreenodeTransmit(temp3, top);
            T.pop();
            *top = T.top();
            TreenodeTransmit(temp4, top);
            T.pop();
            Newnode->Weight = temp3->Weight + temp4->Weight;
            Newnode->Leftnode = temp3,  Newnode->Rightnode = temp4;
            T.push(*Newnode);
        }
    }
    Treenode *toproot = nullptr;
    *toproot = T.top();
    TreenodeTransmit(root, toproot);
}
void Getcode(vector<map<char, string>> *Code, string *tmp, Treenode *root)
{
    if(root->Leftnode == nullptr && root->Rightnode == nullptr)
    {
        map<char, string> t;
        t[root->key] = *tmp;
        Code->push_back(t);
        tmp->erase(tmp->end() - 1);
        return;
    }
    else if(root->Leftnode)
    {
        *tmp += '0';
        Getcode(Code, tmp, root->Leftnode);
    }
    else if(root->Rightnode)
    {
        *tmp += '1';
        Getcode(Code, tmp, root->Rightnode);
    }
    if(tmp->length())
        tmp->erase(tmp->end() - 1);
}
void CompressFile(vector<map<char, string>> *Code, map<char, int> *CharFreq)
{
    fstream infile(TestFile);
    char c;
    string Stream01;
    Stream01.clear();
    while(!infile.eof())
    {
        infile >> c;
        for(auto iter : *Code)
            if(iter.find(c) != iter.end())
                Stream01 += iter[c];
    }
    infile.close();
    fstream outfile;
    outfile.open(BinFile, ios::out | ios::binary);
    for(auto iter : *CharFreq)
    {
        outfile << iter.first << "~" << iter.second << " ";
        cout << iter.first << "~" << iter.second << " " << endl;;
    }
    outfile << "@#";
    while(Stream01.size() >= 8)
    {
        bitset<8> bit(Stream01, 0, 8);
        Stream01.erase(0,8);
        outfile << static_cast<char>(bit.to_ulong());
    }
    if(!Stream01.empty())
    {
        bitset<8> bits(Stream01);
        outfile << static_cast<char>(bits.to_ulong());
    }
    outfile.close();
}
int main()
{
    char c;
    string l;
    map<char, int> Char_Freq;
    map<char, string> Code;
    vector<map<char, string>> CodeT;
    fstream Compress;
    Compress.open("TestFile.txt", ios::in);
    while(!Compress.eof())
    {
        Compress >> c;
        cout << 1;
        Char_Freq[c]++;
    }
    Compress.close();
    BuildHuffmanTree(Char_Freq);
    l.clear();
    Getcode(&CodeT, &l, root);//获得编码集
    CompressFile(&CodeT, &Char_Freq);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值