本文介绍了算术编码的主要思想,并通过分组以5个字符为一组进行编码和译码,实现了对长字符串序列的算术编码,解决了由于实际计算机的精度不可能无限长,运算中出现溢出的问题。
一、算术编码简介:
其是一种无损数据压缩方法,也是一种熵编码的方法,其不同的地方在于,其它的熵编码方法通常是把输入的消息分割为符号,然后对每个符号进行编码。而算术编码是直接把整个输入的消息编码为一个数,一个满足(0.0 ≤ n < 1.0)的小数n。
算术编码用到两个基本的参数:符号的概率和它的编码间隔。信源符号的概率决定压缩编码的效率,也决定编码过程中信源符号的间隔,而这些间隔包含在0到1之间。
二、算术编码的整体流程:
以下是代码实现,先用输入一段较短的英文序列:
clc;
clear;
fp=fopen('duanxulie.txt');%打开文件
首先,读取英文文本,读取字符种类和其对应的频率,也就是概率,之后进行处理,去除各种符号,将其放入一个字符串中
str1=textscan(fp,'%s');%读入字符
str1=str1';
str1=cell2mat(str1{:}');%将所有的单词放到一个字符串中
Newstr=regexprep(str1,'\W','');%去除各种符号,将其转化为空格
Newstr=lower(Newstr);
disp(Newstr);
b = unique(Newstr);
disp(b);
%统计每种字符的个数,放入数组a中
for i = 1 : length(b)
a(i) = length(strfind(Newstr, b(i)));
end
disp(a);
%排序,若数组b中的第一个元素为字符‘a’, 则数组a中的第一个元素为字符‘a’出现的次数
for i = 1 : length(a)-1
for j = i+1 : length(a)
if b(i) > b(j)
t1 = a(i); a(i) = a(j); a(j) = t1;
t2 = b(i); b(i) = b(j); b(j) = t2;
end
end
end
%统计每种字符出现的频率,放入数组fre中
for i = 1 : length(a)
fre(i) = a(i) / sum(a);
end
disp(fre);
%根据频率分配概率范围,范围高值放入H中,范围低值放入L中
Li(1) = 0; Hi(1) = fre(1);
for i = 2 : length(fre)
Li(i) = Hi(i-1);
Hi(i) = Li(i) + fre(i);
end
三、算术编码的主要思想:
(1)对一组信源符号按照符号的概率从大到小排序,将[0,1)设为当前分析区间。按信源符号的概率序列在当前分析区间划分比例间隔。
(2)检索“输入消息序列”,锁定当前消息符号(初次检索的话就是第一个消息符号);找到当前符号在当前分析区间的比例间隔,将此间隔作为新的当前分析区间;并把当前分析区间的起点(即左端点)指示的数“补加”到编码输出数里;当前消息符号指针后移。
(3)仍然按照信源符号的概率序列在当前分析区间划分比例间隔。然后重复第二步;直到“输入消息序列”检索完毕为止。
(4)最后的编码输出数就是编码好的数据。
%编码
L =