要求:高效率压缩字符串
原字符串长度在600到700字节左右,全部为0到9的数字组成,要求压缩后的字符串大小不大于120字节,压缩速度慢些没关系
原字符串长度在600到700字节左右,全部为0到9的数字组成,要求压缩后的字符串大小不大于120字节,压缩速度慢些没关系
解决方案 »
- Delphi 如何给printf和scanf类型的函数传递可变参数
- 兄弟们新年好啊小问题不吝赐教!!!CxGraphics.dcu 是个啥子东西也?我编绎的时候提示没找到是不是个三方控件?
- ACCESS数据按规则顺序存储或提取的算法问题
- 求mdx语法,sql2005
- 系统做好了.要写个程序把分离出来xxx.MDF和xxx.LDF导入到数据库中,怎么办?
- 如何能使程序启动时使用参数?-----------30分
- 请教:COM+中事件(EVENT)的使用?订阅者可以在不同计算机上吗?
- 如何识别Form中是否有ADOQUERY组件?
- 请问那种以ie为内核的浏览器的编程原理是什么?
- 关于applyupdate???
- 监听访问我机子的IP
- NT下DCOM问题,高手来!
是啊,这正是头痛的地方
begin
Case iValue of
0: Result:='0000';
1: Result:='0001';
2: Result:='0010';
3: Result:='0011';
4: Result:='0100';
5: Result:='0101';
6: Result:='0110';
7: Result:='0111';
8: Result:='1000';
9: Result:='1001';
else Result:='';
end;
end;Function BinToOct(sBin:String):Integer;
var
iBit:Integer;
begin
Result:=0; iBit:=0;
While sBin>'' do
begin
Inc(iBit);
if RightStr(sBin,1)='1' then
Result:=Result+Trunc(Power(2,iBit));
Delete(sBin,Length(sBin),1);
end;
end;Function Compress(sSource:String):String;
//压缩由全部位数字组成的字符串
Const
CEnc:Array[0..9] of String = (
'000',
'001',
'010',
'100',
'101',
'110',
'0110',
'0111',
'1110',
'1111'
);
var
iProbability:Array[0..9] of Integer;//字符0到9出现的概率
i,j,iPos,iChar,iTemp:Integer;
sBin,sSeq,sTemp:String;
begin
//求各字符出现的概率
for i:=0 to 9 do iProbability[i]:=0;
for i:=1 to Length(sSource) do
begin
iChar:=StrToInt(sSource[i]);
Inc(iProbability[iChar]);
end; //将各字符的顺序按出现概率的高低排列保存在sSeq中
//冒泡法排序
sSeq:='0123456789';
for i:=0 to 9 do
for j:=i+1 to 9 do
begin
if iProbability[i]>=iProbability[j] then Continue; iTemp:=iProbability[i];
iProbability[i]:=iProbability[j];
iProbability[j]:=iTemp; sTemp:=Copy(sSeq,i+1,1);
sSeq:=LeftStr(sSeq,i)+Copy(sSeq,j+1,1)+Copy(sSeq,i+2,Length(sSeq));
sSeq:=LeftStr(sSeq,j)+sTemp+Copy(sSeq,j+2,Length(sSeq));
end; //按出现概率将原字符串编码成二进制
sBin:='';
for i:=1 to Length(sSource) do
begin
sTemp:=sSource[i];
iPos:=Pos(sTemp,sSeq);
sBin:=sBin+CEnc[iPos-1];
end; //将编码字典保存在二进制字符的前面
for i:=1 to 10 do
sBin:=OctToBin(StrtoInt(sSeq[i]))+sBin; //补足8位
sBin:=sBin+StringOfChar('1',8-(Length(sBin) Mod 8));
//二进制转换为字符输出
Result:='';
While sBin>'' do
begin
Result:=Result+Chr(BinToOct(LeftStr(sBin,8)));
Delete(sBin,1,8);
end;
end;procedure TForm1.Button1Click(Sender: TObject);
var
s,d:String;
iProbability:Array[0..9] of Integer;
i,j:Integer;
begin
s:='';
for i:=1 to 600 do
s:=s+IntToStr(Random(10)); d:=Compress(s);
ShowMessage(IntToStr(Length(s))+#13+IntToStr(Length(d)));
end;
var i,m:integer;
begin
i:=1;
result:='';
while i<= length(s) do
begin
m:=strtoint(copy(s,i,2));
result:=result+chr(m);
i:=i+2;
end;
end;
function decode(s:string):string;
var i,m:integer;
begin
result:='';
for i:=1 to length(s) do
begin
m:=ord(s[i]);
result:=result+inttostr(m);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
memo1.Lines.LoadFromFile('c:\a.txt');
memo1.Text:=decode(memo1.Text);
memo1.Lines.SaveToFile('c:\a.txt');
end;
=========我测了一下 737字节的文件压缩到了369,并能正常解压
既然你这个都是数字,你不妨把它按照9位一截,变成若干个9位的10进制整数。把这9位数用StrToInt变成一个4字节的无符号整形数(2^32大约等于4.2E+10),这不就相当于压缩了吗,还原的时候只要把这个整数用IntToStr就行了,比哈夫曼还简单。它的压缩率大约是 4/9大约44%