就是这个了,你先用着吧。
function GenKeyStr_Single(const Codes:String;MinLength,MaxLength,MinC,MaxC:Integer):String;
var
OriSL:TStringList;
A,Len:array of Integer;
StrBuf:array of Char;
i,n:Integer;
CodeNumber,MinLen,MaxLen,MinCount,MaxCount:Integer;
UsedBufLength,CurLevel:Integer;
procedure GenStr(Level,NeedLen,LeftLen:Integer);
var
ii,nn,k1,k2,TempInt,CLevel:Integer;
MinRemain,MinOccupy:Integer;
mstr:String;
begin
if Level=0 then
begin
if LeftLen>=0 then
begin
mstr:='';
for ii:=0 to CurLevel do
mstr:=OriSL[A[ii]]+mstr;
mstr:=mstr+#13#10;
nn:=Length(mstr);
if UsedBufLength>=MaxBufLength-nn then
begin
UsedBufLength:=MaxInt;
exit;
end;
System.Move(mstr[1],StrBuf[UsedBufLength],nn);
Inc(UsedBufLength,nn);
end;
end
else begin
Level:=Level-1;
MinRemain:=Level*MinLen
//剩余空间必须足以容纳Level个最短的词
MinOccupy:=Level*MaxLen
//必须使Level个最长的词满足最短长度
CLevel:=CurLevel-Level;
TempInt:=A[CLevel];
for ii:=CurLevel-Level to CodeNumber-1 do
begin
k1:=NeedLen-Len[A[ii]];
if k1>MinOccupy then
continue;
k2:=LeftLen-Len[A[ii]];
if k2<MinRemain then
continue;
A[CLevel]:=A[ii]
//交换位置
A[ii]:=TempInt;
GenStr(Level,k1,k2);
A[ii]:=A[CLevel]
//位置还原
A[CLevel]:=TempInt;
end;
end;
end;
begin
Result:='';
OriSL:=TStringList.Create;
OriSL.Text:=Codes;
CodeNumber:=OriSL.Count;
SetLength(Len,CodeNumber);
SetLength(A,CodeNumber);
for i:=0 to CodeNumber-1 do
A
:=i;
MinLen:=Length(OriSL[0]);
MaxLen:=MinLen;
for i:=0 to CodeNumber-1 do
begin
n:=Length(OriSL);
Len:=n;
if n<MinLen then
MinLen:=n;
if n>MaxLen then
MaxLen:=n;
end;
MaxCount:=(MaxLength+MinLen-1) div MinLen
//数组长度上限
if MaxCount>MaxC then
MaxCount:=MaxC;
MinCount:=(MinLength+MaxLen-1) div MaxLen
//层数下限
if MinCount<MinC then
MinCount:=MinC;
SetLength(StrBuf,MaxBufLength+1);
UsedBufLength:=0;
for i:=MinCount to MaxCount do
begin
CurLevel:=i-1;
FillChar(A[0],SizeOf(A),0);
GenStr(i,MinLength,MaxLength);
if UsedBufLength=MaxInt then
exit;
end;
StrBuf[UsedBufLength]:=#0;
Result:=PChar(StrBuf);
OriSL.Free;
SetLength(StrBuf,0);
end;