现在我有一个类似下面这样的字符串(共240个字符),其中我需要获取若干个第m位开始n个字符长的内容,求最佳解法。例如:const
str:='432423480580345723479054280548……7349729340';{公240位}我要取得第
<1>8位开始,4个字符长的子串;
<2>16位后,2个字符长的子串;
<3>……
<i>第k位开始,s个字符长的子串。由于我这里是工业控制方面的系统,因此对时间、空间性能要求很高,希望各位大虾多多援手。
str:='432423480580345723479054280548……7349729340';{公240位}我要取得第
<1>8位开始,4个字符长的子串;
<2>16位后,2个字符长的子串;
<3>……
<i>第k位开始,s个字符长的子串。由于我这里是工业控制方面的系统,因此对时间、空间性能要求很高,希望各位大虾多多援手。
p:array[m..n] of char;
i:integer;
begin
for i:=m ot n do begin
p[m]=str[m];end;
begin
result := '';
if (ACount > 0) and (AFrom > 0) and (AFrom <= Length(AStr)) then
begin
if ACount > Length(AStr) - AFrom + 1 then
ACount := Length(AStr) - AFrom + 1;
SetLength(result, ACount);
Move(AStr[AFrom], result[1], ACount);
end;
end;
TVDataList = Record
rst1:Array [8..9] of Char;
rst2:Array [10..15] of Char;
……
rstk:Array [m..n] of Char;
End;
Function GetResultDataList(strSource : String) : TStrings
var
dlDes : TVDataList;
pStr : PChar;
slTemp: TStringList;
begin
pStr:=@dlDes;
strCopy(pStr,PChar(strSource));
Result.Add(rst1);
Result.Add(rst2);
……
Result.Add(rstk);
if Not(Result.Count > 0) then
begin
Raise Exception.Create('字符拆分过程出现错误');
exit;
end;
end;我觉得这已经是够快的方法了,但是还是不行,还是不够快,真不成让我嵌汇编????
function SubStr(AStr: String; var ADest: ShortString;
AFrom, ACount: Integer): Integer;
begin
// 判断尺寸, 这一段在已知情况下可以省略.
{if ACount > Length(AStr) - AFrom + 1 then
ACount := Length(AStr) - AFrom + 1;
if ACount > 255 then
ACount := 255;} //result := 0;
//if ACount > 0 then
//begin
Move(AStr[AFrom], ADest[1], ACount);
ADest[0] := Char(ACount);
result := ACount;
//end;
end;// 注: str 是已经的串
procedure DivideString;
var
strBuffer: ShortString;
begin
// 第 1 子串
SubStr(str, strBuffer, 8, 4);
//WriteSubStrToTarget(strBuffer); // 第 2 子串
SubStr(str, strBuffer, 16, 2);
//WriteSubStrToTarget(strBuffer); // 第 3 子串
// ... ... // 第 i 子串
SubStr(str, strBuffer, k, s);
//WriteSubStrToTarget(strBuffer);
end;不妨再试一次, 如何?
// 已知存放子串的数组
// arrSub1: array[0..4] of Char;
// arrSub2: array[0..2] of Char;
// ...
// arrSubi: array[0..s] of Char;
procedure DivideString;
begin
// 第 1 子串
Move(str[8], arrSub1, 4);
arrSub1[4] := #0; // 第 2 子串
Move(str[16], arrSub2, 2);
arrSub1[2] := #0; // 第 3 子串
// ... ... // 第 i 子串
Move(str[k], arrSubi, s);
arrSub1[s] := #0;
end;
// 若还不能解决, 现在也只有最后一招了.
// 已知存放子串的数组
// arrSub1: array[0..4] of Char;
// arrSub2: array[0..2] of Char;
// ...
// arrSubi: array[0..s] of Char;
procedure DivideString;
begin
// 第 1 子串
Move(str[8], arrSub1, 4);
arrSub1[4] := #0; // 第 2 子串
Move(str[16], arrSub2, 2);
arrSub2[2] := #0; // 第 3 子串
// ... ... // 第 i 子串
Move(str[k], arrSubi, s);
arrSubi[s] := #0;
end;
该测试结果:经运行 约3.3 /100000*20 组
机器配置:cpu:piii 1G 512内存 delphi7function TForm1.SubStr1(const sStr: String;Const AFrom, ACount: Byte; var dStr:String): integer;
var
i,j:Byte;
begin
if AFrom+ACount<255 then
begin
SetLength(dStr,ACount);
For i:=1 to ACount do
dStr[i] := sStr[AFrom+i-1] ;
end;
end;
procedure TForm1.Test;
var
S: ShortString;
subS1,subS2:string;
d1,d2:Tdatetime;
k:integer;
begin
S := '1234567890234567890134567890121234567890234567890134567890121234567890234567890134567890121234567890234567890134567890121234567890234567890134567890121234567890234567890134567890121234567890234567890134567890121234567890234567890134567890124444';
d1 := now();
k:=1;
repeat
SubStr1(s, 10,20,subS1);
SubStr1(s, 10,20,subS2); SubStr1(s, 20,5,subS1);
SubStr1(s, 20,5,subS2); SubStr1(s, 30,7,subS1);
SubStr1(s, 30,7,subS2); SubStr1(s, 50,9,subS1);
SubStr1(s, 50,9,subS2); SubStr1(s, 77,11,subS1);
SubStr1(s, 81,11,subS2); SubStr1(s, 112,19,subS1);
SubStr1(s, 54,19,subS2); SubStr1(s, 211,4,subS1);
SubStr1(s, 178,37,subS2); SubStr1(s, 179,19,subS1);
SubStr1(s, 165,70,subS2); SubStr1(s, 63,119,subS1);
SubStr1(s, 16,170,subS2); SubStr1(s, 13,200,subS1);
SubStr1(s, 7,220,subS2); inc(k);
until k=100000;
d2 := now();
caption := Formatdatetime('hh:nn:ss:zzz',d2)+'-'+Formatdatetime('hh:nn:ss:zzz',d1);
// 该测试结果:经运行 约3.3 /100000*20 组
//机器配置:cpu:piii 1G 512内存 delphi7
end;
dStr[i] := sStr[AFrom+i-1] ;
比
Move(sStr[AFrom], dStr[1], ACount);
慢多了, Move 在操作时是使用 4 字节 Movsd 指令操作的, 不要快得太多哦!还有, SetLength(dStr, ACount); 这句语句执行的效率极低! 还不如:
//procedure (AStr: String; var ADest: ShortString; AFrom, ACount: Integer);
Move(AStr[AFrom], ADest[1], ACount);
ADest[0] := Char(ACount);
快多了, 重复利用 ADest 局部变量作为交换数据缓冲区, 这样避免不断的分配和释放内存.其实, 我在上面提到的方法已经非常快了, 若还有最快的就是直接定义各个子串常量.