n个0-9的数字怎么压缩使之空间最少 ( 积分: 300 )

  • 主题发起人 主题发起人 中原问鼎
  • 开始时间 开始时间

中原问鼎

Unregistered / Unconfirmed
GUEST, unregistred user!
http://www.ccw.com.cn/htm/app/aprog/01_2_16_2.asp 有现成的例子,本人才疏学浅,翻译不出来,请高手帮忙,写出pas完整的压缩算法和解压算法,并注明
 
http://www.ccw.com.cn/htm/app/aprog/01_2_16_2.asp 有现成的例子,本人才疏学浅,翻译不出来,请高手帮忙,写出pas完整的压缩算法和解压算法,并注明
 
最好在sqlserver中储存过程实现,或者c代码,oracle 储存过程实现.
 
一般 User Zlib
 
看过了,那个算法是用来压缩西文文本的,你的要求比它简单的多,用不着用那样复杂且
压缩比不高的算法。
我的建议是:将这些0-9的数字看成每9位为一组的整数,将这些9位整数构成的字符串转
换成Integer(占用4个字节,压缩前后的空间占用比为9:4),再将Integer当成字符串保存
即可。下面是具体的压缩/解压实现算法代码(为了处理前导0,做了一些特殊处理):
{
名称:纯数字字符串压缩/解压算法
作者:creation_zy
时间:2005-8-17
}
function NumStrZip(const S: String):String;
const
DivLen=9;
var
DivStr,mstr,RemainStr:String;
CurPos,SLen,n:Integer;
begin
Result:='';
if S='' then
exit;
SetLength(mstr,SizeOf(Integer));
CurPos:=1;
SLen:=Length(S);
while SLen-CurPos>=DivLen-1do
begin
DivStr:='-1'+Copy(S,CurPos,DivLen);
//为了避免丢失前导0,用 '-1'作为前缀
Inc(CurPos,DivLen);
n:=StrToInt(DivStr);
Move(n,mstr[1],SizeOf(Integer));
Result:=Result+mstr;
end;
RemainStr:=Copy(S,CurPos,DivLen);
if RemainStr<>'' then
//最后一组长度不足的数字串
begin
DivStr:='-1'+RemainStr;
n:=StrToInt(DivStr);
Move(n,mstr[1],SizeOf(Integer));
while mstr[Length(mstr)]=#255do
//将尾部的$FF截除,以减短最终结果的长度
Delete(mstr,Length(mstr),1);
Result:=Result+mstr;
end;
end;

function UnzipStr2NumStr(const S: String):String;
const
DivLen=9;
var
DivStr,mstr,RemainStr:String;
CurPos,SLen,n:Integer;
begin
Result:='';
if S='' then
exit;
CurPos:=1;
SLen:=Length(S);
while SLen-CurPos>=SizeOf(Integer)-1do
begin
Move(S[CurPos],n,SizeOf(Integer));
mstr:=IntToStr(n);
Result:=Result+Copy(mstr,3,DivLen);
//忽略前缀 '-1'
Inc(CurPos,SizeOf(Integer));
end;
RemainStr:=Copy(S,CurPos,SizeOf(Integer));
if RemainStr<>'' then
//最后一组长度不足的数字串
begin
FillChar(n,4,$FF);
//用$FF填充整个串
Move(RemainStr[1],n,Length(RemainStr));
mstr:=IntToStr(n);
Result:=Result+Copy(mstr,3,DivLen);
//忽略前缀 '-1'
end;
end;

//下面是样例代码
function Str2Hex(const S: String): String;
register;
asm
push ebx
push esi
push edi
mov ebx, edx
mov edi, eax
call System.@LStrLen
mov edx, eax
mov esi, eax
add edx, edx
mov eax, ebx
call System.@LStrSetLength
test esi, esi
jle @@2
mov eax, ebx
call System.UniqueString
@@1: xor edx, edx
mov dl, [edi]
mov ebx, edx
shr edx, 04h
mov dl, byte ptr[edx+@@3]
and ebx, 0Fh
mov [eax], dl
mov dl, byte ptr[ebx+@@3]
inc eax
inc edi
mov [eax], dl
inc eax
dec esi
jnz @@1
@@2: pop edi
pop esi
pop ebx
ret
@@3: db '0123456789ABCDEF'
end;

procedure TForm1.Button2Click(Sender: TObject);
var
OriNumStr,mstr,FinalStr:String;
begin
OriNumStr:=Trim(Memo1.Text);
//原始字符串——必须是由纯数字组成
if OriNumStr='' then
Button1.Click;
mstr:=NumStrZip(OriNumStr);
//压缩
SpinEdit2.Value:=Length(mstr);
//获取长度
Memo2.Text:=Str2Hex(mstr);
//以16进制显示压缩后的字符串
FinalStr:=UnzipStr2NumStr(mstr);
//解压缩
Memo3.Text:=FinalStr;
//显示
end;
 
后退
顶部