arithcode.m

来自「本代码参考David《数据压缩原理与应用》P71-P82,实现了有限精度的算术编」· M 代码 · 共 53 行

M
53
字号
%******************************************************************************************
% 算术编码(Arithmetic Coding)
%******************************************************************************************
function [Code,P]=ArithCode(x)
% 参考文献:
% 数据压缩原理与应用(第二版)[美]David Salomon 著 pp:71-82
x=input('请输入编码的字符串:');
P=Freq_Stat(x);
% 根据结构体P计算频率
LowCumFreq=zeros(length(P),1);
HighCumFreq=zeros(length(P),1);
HighCumFreq(1)=P(1).Freq;
for i=2:length(P)
    LowCumFreq(i)=LowCumFreq(i-1)+P(i-1).Freq;
    HighCumFreq(i)=LowCumFreq(i)+P(i).Freq;
end
% 初始化
Len=length(x);
CodeLen=0; % 初始码长设为0
Code=0; % 初始化编码结果
Low=0;High=1; % 初始化Low和High

% 逐个进行编码
for i=1:Len
    for j=1:length(P)
        if x(i)==P(j).Value
           NUM=P(j).Num;
        end
    end
    % LowT,HighT分别用语暂存Low和High
    LowT=Low;
    HighT=High;
    Low=LowT+(HighT-LowT)*(LowCumFreq(NUM)/HighCumFreq(length(P)));
    High=LowT+(HighT-LowT)*(HighCumFreq(NUM)/HighCumFreq(length(P)));
    % 对Low和High重定标
    Low=floor(Low*10^4);
    High=floor(High*10^4-1);
    % 一旦Low和High最左边的数字相等,则将最左边的数字写入输出流
    while floor(Low/1000)==floor(High/1000)
       CodeLen=CodeLen+1;% 码长加1
       Code=Code*10+floor(Low/1000);
       Low=(Low-floor(Low/1000)*1000)*10+0;% Low的右端移入0,High的右端移入9
       High=(High-floor(High/1000)*1000)*10+9;
    end
    % Low和High更新,还原为小数
    Low=Low/10^4;
    High=(High+1)/10^4; 
end

% 形成最终的码字
CodeLen=CodeLen+4; % 加上最终四位码子作为总的码长
Code=Code*10^4+floor(Low*10^4); % 编码最后4位

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?