例5-10 有4个符号a,b,c,d构成简单序列S=(a,b,d,a),各符号及其对应概率如下表5-9所列。
符号 | 符号概率pi | 符号累积概率Pj |
a | 0.100(1/2) | 0.000 |
b | 0.010(1/4) | 0.100 |
c | 0.001(1/8) | 0.110 |
d | 0.001(1/8) | 0.111 |
答:算术编码的基本思想是:将输入序列的各个符号按照出现的概率映像到0~1之间数字区域内,该区域表示成可以改变精度的二进制小数,其中出现频率越低的数据利用精度越高的小数表示。算术压缩算法中两个基本的要素为源数据出现的频率以及对应的编码区间。其中,源数据出现的频率决定该算法的压缩效果,同时也决定编码过程中源数据对应的区间范围,而编码区间则决定算术压缩算法的最终输出数据。
对“a,b,d,a”进行算术编码的步骤如下:
1)初始化时,被分割范围的初始值是[0,1),即被分割范围的下限为low=0,上限为 high =1,该范围的长度为range_length=high-low =1。
2)根据算术编码的公式:C(s,r)=C(S)+A(S)Pr
A(S,r)=A(S)Pr
其中采用积累概率P(S)表示码字C(S),符号概率p(S)表示区间状态A(S)。因为是二进制符号组成的序列,所以r=0,1。
将数据带入公式求得C(a,b,d,a)编码后的码字为01011,Matlab程序具体实现过程如下所示
K=menu('choose whether you want to enter a character or a number','enter character','enter number')
if K==1;
str=input('请输入编码的字符串:');
l=0;r=1;d=1;
p=[0.5 0.25 0.125 0.125];
n=length(str);
disp('a b c d ')
disp(num2str(p))
for i=1:n
switch str(i)
case 'a'
m=1;
case 'b'
m=2;
case 'c'
m=3;
case 'd'
m=4;
otherwise
error('请不要输入其它字符!');
end
%判断字符
pl=0;pr=0;
for j=1:(m-1 )
pl=pl+p(j);
end
for j=1:m
pr=pr+p(j);
end
%概率统计
l=l+d*pl;
r=l+d*(pr-pl);
strl=strcat('输入第',int2str(i),'符号的间隔左右边界:');
disp(strl);
format long
disp(l);disp(r);
d=r-l;
end %for循环借结束
result=l
else K==2
LP1(1)=0;
p=[0.5 0.25 0.125 0.125];
for i=1:3
LP1(i+1)=LP1(i)+p(i);
end
result=input('please enter the number');
while(result<0.975 )
if (result>=0 & result<0.5)
disp('a')
elseif (result>=0.5 &result<0.75)
disp('b')
elseif (result>=0.75 &result<0.875)
disp('c')
elseif (result>=0.875 &result<0.975)
disp('d')
end
for j=1:4
if (result>=LP1(j) &result<LP1(j+1))
result=(result-LP1(j))/(LP1(j+1)-LP1(j))
break;
else continue;
end
end
end %while
disp('!')
disp('解码结束')
end %if else
编码结果如下:请输入编码的字符串:'abda'
a b c d
0.5 0.25 0.125 0.125
输入第1符号的间隔左右边界:
0
0.50000000000000
输入第2符号的间隔左右边界:
0.25000000000000
0.37500000000000
输入第3符号的间隔左右边界:
0.35937500000000
0.37500000000000
输入第4符号的间隔左右边界:
0.35937500000000
0.36718750000000
result =
0.35937500000000