西北工业大学数据结构noj3-1

3-1哈夫曼编译码器

question

问号为空格

完整代码

// 哈夫曼编/译码器
#include <iostream>
#include <vector>
#include <string>

#define MAX_Weight 65535

struct HTNode
{
    int weight = 0, parent = 0, LChild = 0, RChlid = 0;
    // int weight, parent, LChild, RChlid;
    std::string code = "";
    char data = '\0';
};

void InitHuffman(std::vector<HTNode> &ht, std::vector<int> weight, std::string st, int n);

void CreatHuffman(std::vector<HTNode> &ht, int n);

void Select(std::vector<HTNode> ht, int n, int &s1, int &s2);

void ShowHuffman(std::vector<HTNode> ht);

void Encoding(std::vector<HTNode> &ht, int n);

std::string Decoding(std::vector<HTNode> ht, std::string code);

int main()
{
    int n;
    std::cin >> n;
    std::string st = "";
    char ch;
    for (auto i = 0; i < n; ++i)
    {
        std::cin >> ch;
        st += ch;
    }

    int w;
    std::vector<int> weight;
    for (auto i = 0; i < n; ++i)
    {
        std::cin >> w;
        weight.emplace_back(w);
    }

    std::string source;
    std::cin >> source;

    std::vector<HTNode> ht((n << 1) - 1);

    InitHuffman(ht, weight, st, n);
    CreatHuffman(ht, n);
    // ShowHuffman(ht);

    Encoding(ht, n);
    std::string encode = "";
    for (auto i = 0; i < source.size(); ++i)
    {
        for (auto j = 0; j < n; ++j)
        {
            if (ht[j].data == source[i])
                encode += ht[j].code;
        }
    }

    std::cout << encode << std::endl;

    std::string decode = Decoding(ht, encode);

    std::cout << Decoding(ht, encode) << std::endl;

    system("pause");
    return 0;
}

void InitHuffman(std::vector<HTNode> &ht, std::vector<int> weight, std::string st, int n)
{
    for (auto i = 0; i < n; ++i)
    {
        ht[i].data = st[i];
        ht[i].weight = weight[i];
        ht[i].parent = 0;
        ht[i].LChild = 0;
        ht[i].RChlid = 0;
        // ht[i] = {weight[i], 0, 0, 0, st[i]};
    }

    int m = ht.size();
    for (auto i = n; i < m; ++i)
    {
        ht[i].weight = 0;
        ht[i].parent = 0;
        ht[i].LChild = 0;
        ht[i].RChlid = 0;
        ht[i].data = '\0';
    }
}
// 5 e a s c t 5 7 3 2 8
void CreatHuffman(std::vector<HTNode> &ht, int n)
{
    int s1, s2;
    int m = ht.size();
    for (auto i = n; i < m; ++i)
    {
        Select(ht, i, s1, s2);
        ht[i].weight = ht[s1].weight + ht[s2].weight;
        ht[i].LChild = s1, ht[i].RChlid = s2;
        ht[s1].parent = ht[s2].parent = i;
    }
}

void Select(std::vector<HTNode> ht, int n, int &s1, int &s2)
{
    int left = MAX_Weight, right = MAX_Weight;

    for (auto i = 0; i < n; ++i)
    {
        if (ht[i].parent == 0)
        {
            if (ht[i].weight < left)
            {
                right = left;
                s2 = s1;
                left = ht[i].weight;
                s1 = i;
            }
            else if (ht[i].weight < right)
            {
                right = ht[i].weight;
                s2 = i;
            }
        }
    }
    // s1  = left_idx, s2 = right_idx;
}

void ShowHuffman(std::vector<HTNode> ht)
{
    int m = ht.size();
    for (auto i = 0; i < m; ++i)
    {
        std::cout << ht[i].weight << " " << ht[i].parent << " " << ht[i].LChild << " " << ht[i].RChlid << std::endl;
    }
}

void Encoding(std::vector<HTNode> &ht, int n)
{
    int child, parent;
    std::string code;

    for (auto i = 0; i < n; ++i)
    {
        child = i;
        parent = ht[i].parent;
        code = "";
        while (parent)
        {
            if (child == ht[parent].LChild)
                code += '0';
            else
                code += '1';
            child = parent;
            parent = ht[parent].parent;
        }
        ht[i].code.assign(code.rbegin(), code.rend());
    }
}

std::string Decoding(std::vector<HTNode> ht, std::string code)
{
    std::string result = "";
    int len = code.size();
    int m = ht.size();
    int idx = m - 1;
    int cur = 0;

    while (cur < len)
    {
        if (code[cur] == '0')
            idx = ht[idx].LChild;
        else
            idx = ht[idx].RChlid;

        if (ht[idx].LChild == 0 && ht[idx].RChlid == 0)
        {
            result += ht[idx].data;
            idx = m - 1;
        }
        cur++;
    }

    return result;
}

// 5 a b c d e 12 40 15 8 25
//  bbbaddeccbbb

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值