上一篇
在数据压缩领域,算术编码是一种高效且强大的无损压缩算法。与霍夫曼编码不同,它能将整个消息编码为一个介于0和1之间的实数,从而更接近信息熵的理论极限。本文将带你从零开始,用C++语言实现一个简易但完整的算术编码算法,即使是编程小白也能轻松理解!
算术编码的核心思想是:将输入符号序列映射到 [0, 1) 区间中的一个子区间,该子区间的长度等于该序列出现的概率。解码时,只需知道这个最终的小数,就能逆向还原原始序列。

图:算术编码通过不断缩小区间来表示符号序列
在实现前,我们需要一个简单的概率模型。假设我们要压缩字符串 "ABAC",其中:
我们将使用这些概率来划分区间。
#include <iostream>#include <map>#include <string>#include <vector>#include <iomanip>// 符号到累积概率的映射(左边界)std::map<char, double> buildCumulativeProb(const std::map<char, double>& prob) { std::map<char, double> cumProb; double sum = 0.0; for (const auto& p : prob) { cumProb[p.first] = sum; sum += p.second; } return cumProb;}double arithmeticEncode(const std::string& message, const std::map<char, double>& prob, const std::map<char, double>& cumProb) { double low = 0.0; double high = 1.0; for (char c : message) { if (prob.find(c) == prob.end()) { std::cerr << "Unknown symbol: " << c << std::endl; return -1; } double range = high - low; double symbolLow = cumProb.at(c); double symbolHigh = symbolLow + prob.at(c); high = low + range * symbolHigh; low = low + range * symbolLow; std::cout << "Symbol '" << c << "': [" << std::setprecision(6) << low << ", " << high << ")\n"; } // 返回区间中点作为编码结果 return (low + high) / 2.0;}std::string arithmeticDecode(double encodedValue, int length, const std::map<char, double>& prob, const std::map<char, double>& cumProb) { std::string result; double value = encodedValue; for (int i = 0; i < length; ++i) { for (const auto& p : prob) { char symbol = p.first; double lowBound = cumProb.at(symbol); double highBound = lowBound + p.second; if (value >= lowBound && value < highBound) { result += symbol; // 将值归一化到当前符号区间内 value = (value - lowBound) / p.second; break; } } } return result;}int main() { // 定义符号概率 std::map<char, double> prob = {{'A', 0.5}, {'B', 0.25}, {'C', 0.25}}; auto cumProb = buildCumulativeProb(prob); std::string message = "ABAC"; std::cout << "Original message: " << message << "\n\n"; // 编码 double encoded = arithmeticEncode(message, prob, cumProb); std::cout << "\nEncoded value: " << std::setprecision(10) << encoded << "\n\n"; // 解码 std::string decoded = arithmeticDecode(encoded, message.length(), prob, cumProb); std::cout << "Decoded message: " << decoded << "\n"; if (message == decoded) { std::cout << "✅ Success! Compression and decompression work correctly.\n"; } else { std::cout << "❌ Error! Decoded message does not match original.\n"; } return 0;}程序输出如下:
Original message: ABACSymbol 'A': [0, 0.5)Symbol 'B': [0.25, 0.375)Symbol 'A': [0.25, 0.3125)Symbol 'C': [0.296875, 0.3125)Encoded value: 0.3046875Decoded message: ABAC✅ Success! Compression and decompression work correctly.
通过本教程,你已经掌握了如何用 C++算术编码 实现基础的 无损压缩算法。虽然这是一个简化版本,但它完整展示了 算术编码算法 的核心逻辑。理解这一过程,为你深入学习 C++数据压缩 技术打下了坚实基础。
下一步建议:尝试将浮点运算改为整数运算,或集成到文件压缩工具中!
本文由主机测评网于2025-12-17发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025129163.html