如何用最快速遍历一个超大字符串,大概1M多? 如何用最快速遍历一个超大字符串,大概1M多?没有快速遍历方法,拆分字符串会很慢? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 首先你要找什么?只找找的话用Pos('??',Str) 就OK了 要看你怎样遍历了。简单的用 Pos 即可。如果复杂一些的应用,例如查找多个子串、替换子串可以看看《传说中世界上最快的查找和替换函数:(大富翁DreamTiger原创)》unit FastString;interfaceTypeTFastPosProc = function( const aSourceString, aFindString : String; const aSourceLen, aFindLen, StartPos : integer) : integer; function __FastReplace( var aSourceString : String; const aFindString, aReplaceString : String; CaseSensitive : Boolean = False) : String; function __FastPos( const aSourceString, aFindString : String; const aSourceLen, aFindLen, StartPos : integer ) : integer; function __FastPosNoCase( const aSourceString, aFindString : String; const aSourceLen, aFindLen, StartPos : integer ) : integer; implementationfunction __FastPos( const aSourceString, aFindString : String; const aSourceLen, aFindLen, StartPos : integer ) : integer; var SourceLen : integer; begin SourceLen := aSourceLen; SourceLen := SourceLen - aFindLen; if (StartPos-1) > SourceLen then begin Result := 0; Exit; end; SourceLen := SourceLen - StartPos; SourceLen := SourceLen +2; asm push ESI push EDI push EBX mov EDI, aSourceString add EDI, StartPos Dec EDI mov ESI, aFindString mov ECX, SourceLen Mov Al, [ESI] @ScaSB: Mov Ah, [EDI] cmp Ah,Al jne @NextChar @CompareStrings: mov EBX, aFindLen dec EBX Jz @EndOfMatch @CompareNext: mov Al, [ESI+EBX] mov Ah, [EDI+EBX] cmp Al, Ah Jz @Matches Mov Al, [ESI] Jmp @NextChar @Matches: Dec EBX Jnz @CompareNext @EndOfMatch: mov EAX, EDI sub EAX, aSourceString inc EAX mov Result, EAX jmp @TheEnd @NextChar: Inc EDI dec ECX jz @Result0 cmp ah, $80 jb @ScaSB Inc EDI Dec ECX jnz @ScaSB @Result0: mov Result,0 @TheEnd: pop EBX pop EDI pop ESI end; end;function __FastPosNoCase( const aSourceString, aFindString : String; const aSourceLen, aFindLen, StartPos : integer ) : integer; var SourceLen : integer;begin SourceLen := aSourceLen; SourceLen := SourceLen - aFindLen; if (StartPos-1) > SourceLen then begin Result := 0; Exit; end; SourceLen := SourceLen - StartPos; SourceLen := SourceLen +2; asm push ESI push EDI push EBX mov EDI, aSourceString add EDI, StartPos Dec EDI mov ESI, aFindString mov ECX, SourceLen Mov Al, [ESI] cmp Al, $7A ja @ScaSB cmp Al, $61 jb @ScaSB and Al, $df @ScaSB: Mov Ah, [EDI] cmp Ah, $7A ja @CompareChar cmp Ah, $61 jb @CompareChar and Ah, $df @CompareChar: cmp Ah,Al jne @NextChar @CompareStrings: mov EBX, aFindLen dec EBX Jz @EndOfMatch @CompareNext: mov Al, [ESI+EBX] mov Ah, [EDI+EBX] cmp Ah, $7A ja @LowerAh cmp Al, $61 jb @LowerAh and Al, $df @LowerAh: cmp Ah, $7A ja @CompareChar2 cmp Ah, $61 jb @CompareChar2 and Ah, $df @CompareChar2: cmp Al, Ah Jz @Matches Mov Al, [ESI] cmp Al, $7A ja @NextChar cmp Al, $61 jb @NextChar and Al, $df Jmp @NextChar @Matches: Dec EBX Jnz @CompareNext @EndOfMatch: mov EAX, EDI sub EAX, aSourceString inc EAX mov Result, EAX jmp @TheEnd @NextChar: Inc EDI dec ECX jz @Result0 cmp ah, $80 jb @ScaSB Inc EDI Dec ECX jnz @ScaSB @Result0: mov Result,0 @TheEnd: pop EBX pop EDI pop ESI end; end;procedure MyMove( const Source; var Dest; Count : Integer);asm cmp ECX,0 Je @JustQuit push ESI push EDI mov ESI, EAX mov EDI, EDX @Loop: Mov AL, [ESI] Inc ESI mov [EDI], AL Inc EDI Dec ECX Jnz @Loop pop EDI pop ESI @JustQuit: end;function __FastReplace( var aSourceString : String; const aFindString, aReplaceString : String; CaseSensitive : Boolean = False) : String; var ActualResultLen, CurrentPos, LastPos, BytesToCopy, ResultLen, FindLen, ReplaceLen, SourceLen : Integer; FastPosProc : TFastPosProc; begin if CaseSensitive then FastPosProc := __FastPos else FastPOSProc := __FastPOSNoCase; Result := ''; FindLen := Length(aFindString); ReplaceLen := Length(aReplaceString); SourceLen := Length(aSourceString); if ReplaceLen <= FindLen then ActualResultLen := SourceLen else ActualResultLen := SourceLen + (SourceLen * ReplaceLen div FindLen) + ReplaceLen; SetLength(Result,ActualResultLen); CurrentPos := 1; ResultLen := 0; LastPos := 1; if ReplaceLen > 0 then begin repeat CurrentPos := FastPosProc(aSourceString, aFindString, SourceLen, FindLen, CurrentPos); if CurrentPos = 0 then break; BytesToCopy := CurrentPos-LastPos; MyMove(aSourceString[LastPos], Result[ResultLen+1], BytesToCopy); MyMove(aReplaceString[1], Result[ResultLen+1+BytesToCopy], ReplaceLen); ResultLen := ResultLen + BytesToCopy + ReplaceLen; CurrentPos := CurrentPos + FindLen; LastPos := CurrentPos; until false; end else begin repeat CurrentPos := __FastPos(aSourceString, aFindString, SourceLen, FindLen, CurrentPos); if CurrentPos = 0 then break; BytesToCopy := CurrentPos-LastPos; MyMove(aSourceString[LastPos], Result[ResultLen+1], BytesToCopy); ResultLen := ResultLen + BytesToCopy + ReplaceLen; CurrentPos := CurrentPos + FindLen; LastPos := CurrentPos; until false; end; Dec(LastPOS); SetLength(Result, ResultLen + (SourceLen-LastPos)); if LastPOS+1 <= SourceLen then MyMove(aSourceString[LastPos+1], Result[ResultLen+1],SourceLen-LastPos); end; end. 好久没来,散分看望大家 始终最上面? 怎么由子窗口句柄得到主窗口句柄? 简单问题,大家快来抢分!!!!! cxgrid绑定需要加密的数据 小弟祝各位中秋快乐,先请教一个问题 急问数据表字段编辑器中lookup字段问题 请问我怎样动态的远程获得ClientDataSet的DataSetProvider????? 我是初学者,请各位高手教我! 求助:回调函数指针的用法 招delphi开发人员(佛山) 高分求windows技术内幕下载地址
用Pos('??',Str) 就OK了
简单的用 Pos 即可。如果复杂一些的应用,例如查找多个子串、替换子串
可以看看《传说中世界上最快的查找和替换函数:(大富翁DreamTiger原创)》unit FastString;interfaceType
TFastPosProc = function(
const aSourceString, aFindString : String;
const aSourceLen, aFindLen, StartPos : integer
) : integer; function __FastReplace(
var aSourceString : String;
const aFindString, aReplaceString : String;
CaseSensitive : Boolean = False) : String; function __FastPos(
const aSourceString, aFindString : String;
const aSourceLen, aFindLen, StartPos : integer
) : integer; function __FastPosNoCase(
const aSourceString, aFindString : String;
const aSourceLen, aFindLen, StartPos : integer
) : integer; implementationfunction __FastPos(
const aSourceString, aFindString : String;
const aSourceLen, aFindLen, StartPos : integer
) : integer;
var
SourceLen : integer;
begin
SourceLen := aSourceLen;
SourceLen := SourceLen - aFindLen;
if (StartPos-1) > SourceLen then begin
Result := 0;
Exit;
end;
SourceLen := SourceLen - StartPos;
SourceLen := SourceLen +2;
asm
push ESI
push EDI
push EBX
mov EDI, aSourceString
add EDI, StartPos
Dec EDI
mov ESI, aFindString
mov ECX, SourceLen
Mov Al, [ESI]
@ScaSB:
Mov Ah, [EDI]
cmp Ah,Al
jne @NextChar
@CompareStrings:
mov EBX, aFindLen
dec EBX Jz @EndOfMatch @CompareNext:
mov Al, [ESI+EBX]
mov Ah, [EDI+EBX]
cmp Al, Ah
Jz @Matches
Mov Al, [ESI]
Jmp @NextChar
@Matches:
Dec EBX
Jnz @CompareNext @EndOfMatch: mov EAX, EDI
sub EAX, aSourceString
inc EAX
mov Result, EAX
jmp @TheEnd
@NextChar:
Inc EDI
dec ECX jz @Result0
cmp ah, $80
jb @ScaSB
Inc EDI
Dec ECX jnz @ScaSB @Result0: mov Result,0
@TheEnd:
pop EBX
pop EDI
pop ESI
end;
end;function __FastPosNoCase(
const aSourceString, aFindString : String;
const aSourceLen, aFindLen, StartPos : integer
) : integer;
var
SourceLen : integer;
begin
SourceLen := aSourceLen;
SourceLen := SourceLen - aFindLen;
if (StartPos-1) > SourceLen then begin
Result := 0;
Exit;
end;
SourceLen := SourceLen - StartPos;
SourceLen := SourceLen +2;
asm
push ESI
push EDI
push EBX mov EDI, aSourceString
add EDI, StartPos
Dec EDI
mov ESI, aFindString
mov ECX, SourceLen
Mov Al, [ESI] cmp Al, $7A
ja @ScaSB cmp Al, $61
jb @ScaSB and Al, $df @ScaSB:
Mov Ah, [EDI] cmp Ah, $7A
ja @CompareChar cmp Ah, $61
jb @CompareChar and Ah, $df @CompareChar:
cmp Ah,Al
jne @NextChar
@CompareStrings:
mov EBX, aFindLen
dec EBX Jz @EndOfMatch @CompareNext:
mov Al, [ESI+EBX]
mov Ah, [EDI+EBX] cmp Ah, $7A
ja @LowerAh cmp Al, $61
jb @LowerAh and Al, $df @LowerAh:
cmp Ah, $7A
ja @CompareChar2 cmp Ah, $61
jb @CompareChar2 and Ah, $df @CompareChar2:
cmp Al, Ah
Jz @Matches
Mov Al, [ESI] cmp Al, $7A
ja @NextChar cmp Al, $61
jb @NextChar and Al, $df
Jmp @NextChar
@Matches:
Dec EBX
Jnz @CompareNext @EndOfMatch: mov EAX, EDI
sub EAX, aSourceString
inc EAX
mov Result, EAX
jmp @TheEnd
@NextChar:
Inc EDI
dec ECX
jz @Result0
cmp ah, $80
jb @ScaSB
Inc EDI
Dec ECX
jnz @ScaSB
@Result0:
mov Result,0
@TheEnd:
pop EBX
pop EDI
pop ESI
end;
end;procedure MyMove(
const Source; var Dest; Count : Integer);
asm
cmp ECX,0
Je @JustQuit
push ESI
push EDI
mov ESI, EAX
mov EDI, EDX
@Loop:
Mov AL, [ESI]
Inc ESI
mov [EDI], AL
Inc EDI
Dec ECX
Jnz @Loop
pop EDI
pop ESI
@JustQuit:
end;function __FastReplace(
var aSourceString : String;
const aFindString, aReplaceString : String;
CaseSensitive : Boolean = False) : String;
var
ActualResultLen,
CurrentPos,
LastPos,
BytesToCopy,
ResultLen,
FindLen,
ReplaceLen,
SourceLen : Integer;
FastPosProc : TFastPosProc;
begin
if CaseSensitive then
FastPosProc := __FastPos
else
FastPOSProc := __FastPOSNoCase; Result := '';
FindLen := Length(aFindString);
ReplaceLen := Length(aReplaceString);
SourceLen := Length(aSourceString);
if ReplaceLen <= FindLen then
ActualResultLen := SourceLen
else
ActualResultLen :=
SourceLen +
(SourceLen * ReplaceLen div FindLen) +
ReplaceLen;
SetLength(Result,ActualResultLen);
CurrentPos := 1;
ResultLen := 0;
LastPos := 1;
if ReplaceLen > 0 then begin
repeat
CurrentPos :=
FastPosProc(aSourceString, aFindString,
SourceLen, FindLen, CurrentPos);
if CurrentPos = 0 then break;
BytesToCopy := CurrentPos-LastPos;
MyMove(aSourceString[LastPos],
Result[ResultLen+1], BytesToCopy);
MyMove(aReplaceString[1],
Result[ResultLen+1+BytesToCopy], ReplaceLen);
ResultLen := ResultLen +
BytesToCopy + ReplaceLen;
CurrentPos := CurrentPos + FindLen;
LastPos := CurrentPos;
until false;
end else begin
repeat
CurrentPos := __FastPos(aSourceString,
aFindString, SourceLen, FindLen, CurrentPos);
if CurrentPos = 0 then break;
BytesToCopy := CurrentPos-LastPos;
MyMove(aSourceString[LastPos],
Result[ResultLen+1], BytesToCopy);
ResultLen := ResultLen +
BytesToCopy + ReplaceLen;
CurrentPos := CurrentPos + FindLen;
LastPos := CurrentPos;
until false;
end;
Dec(LastPOS);
SetLength(Result, ResultLen + (SourceLen-LastPos));
if LastPOS+1 <= SourceLen then
MyMove(aSourceString[LastPos+1],
Result[ResultLen+1],SourceLen-LastPos);
end; end.