压缩算法,哈夫曼编码,字符串压缩

哈夫曼编码是一种常用的无损压缩算法,它通过构建最优前缀编码来实现数据的压缩。哈夫曼编码的原理是根据符号出现的频率来构建一个最优的二叉树(哈夫曼树),并将出现频率高的符号用较短的编码表示,出现频率低的符号用较长的编码表示。

步骤:
统计输入数据中每个符号的出现频率。
根据频率构建哈夫曼树。首先创建一个包含所有符号的叶子节点集合,每个节点的权重为符号的频率。然后重复以下步骤直到只剩下一个根节点:
从节点集合中选择两个权重最小的节点,作为左右子节点创建一个新的父节点。
将新节点的权重设为左右子节点权重之和。
将新节点加入节点集合。
从节点集合中删除原先选出的两个节点。
根据哈夫曼树为每个符号分配唯一的编码。从根节点出发,沿着左子树走为0,沿着右子树走为1,记录下路径上的0和1即为符号的编码。
使用生成的编码对输入数据进行压缩。将每个符号替换为对应的编码。
将压缩后的数据以及编码表(记录每个符号的编码)一起保存,以便解压缩时使用。

from heapq import heapify, heappush, heappop
from collections import defaultdict


def build_huffman_tree(freq_dict):
    """构建哈夫曼树"""
    heap = [[freq, [char, ""]] for char, freq in freq_dict.items()]
    heapify(heap)

    while len(heap) > 1:
        lo = heappop(heap)
        hi = heappop(heap)
        for pair in lo[1:]:
            pair[1] = '0' + pair[1]
        for pair in hi[1:]:
            pair[1] = '1' + pair[1]
        heappush(heap, [lo[0] + hi[0]] + lo[1:] + hi[1:])

    return sorted(heappop(heap)[1:], key=lambda x: (len(x[-1]), x))


def encode(data):
    """对数据进行哈夫曼编码"""
    freq_dict = defaultdict(int)
    for char in data:
        freq_dict[char] += 1

    huffman_tree = build_huffman_tree(freq_dict)
    encoding_dict = dict(huffman_tree)

    encoded_data = ""
    for char in data:
        encoded_data += encoding_dict[char]

    return encoded_data, encoding_dict


def decode(encoded_data, encoding_dict):
    """对哈夫曼编码进行解码"""
    decoding_dict = {v: k for k, v in encoding_dict.items()}

    decoded_data = ""
    code = ""
    for bit in encoded_data:
        code += bit
        if code in decoding_dict:
            decoded_data += decoding_dict[code]
            code = ""

    return decoded_data


data = "mississippi river"
encoded_data, encoding_dict = encode(data)
decoded_data = decode(encoded_data, encoding_dict)

print("原始数据:", data)
print("编码后的数据:", encoded_data)
print("解码后的数据:", decoded_data)

原始数据: mississippi river
编码后的数据: 11101110100000111011110110011101100000010111110101
解码后的数据: mississippi river
  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__WHOAMI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值