L
LSUPER
Unregistered / Unconfirmed
GUEST, unregistred user!
function FindPosBM(const ASub, ASource: string
AStartPos: Integer = 1): Integer;
const
MAX_CHAR = 256;
SizeInt = SizeOf(Integer);
type
PByteArr = ^TByteArr;
TByteArr = array[0..MaxInt - 1] of Byte;
var
Src, Sub: PByte;
I, J, CurrPos, SubLen, SrcLen: Integer;
Buffer: array[0..MAX_CHAR - 1] of Integer;
begin
Result := 0;
SubLen := Length(ASub);
SrcLen := Length(ASource);
if SubLen > SrcLen then
Exit;
Sub := PByte(ASub);
Src := PByte(ASource);
for I := 0 to MAX_CHAR - 1 do
Buffer := SubLen;
for I := 0 to SubLen - 2 do
Buffer[PByteArr(Sub)^] := SubLen - I - 1;
CurrPos := SubLen + AStartPos - 2;
while CurrPos < SrcLen do
begin
I := CurrPos;
J := SubLen - 1;
while (J >= 0) and ((PByteArr(Src)^ = PByteArr(Sub)^[J])) do
begin
Dec(J);
Dec(I);
end;
if - 1 = J then
begin
Result := CurrPos - SubLen + 1;
break;
end;
Inc(CurrPos, Buffer[PByteArr(Src)^[CurrPos]]);
end;
end;
function BMH(const lpSubStr, lpSource: string
StartPos: Integer = 1): Integer;
var
I, index, ExitLen: Integer;
CharTable: array[0..255] of Char;
begin
if Length(lpSubStr) < 1 then
begin
Result := -2
// 子字符串长度不能小于1位
Exit;
end;
// 初始化CharTable
FillChar(CharTable, sizeof(CharTable), Char(Length(lpSubStr)));
for I := Length(lpSubStr) downto 1 do
CharTable[Ord(lpSubStr)] := Char(Length(lpSubStr) - I);
if StartPos < 1 then
I := StartPos
else
I := StartPos - 1;
ExitLen := Length(lpSource) - Length(lpSubStr);
while I <= ExitLen do
begin
for index := Length(lpSubStr) downto 1 do
begin
if lpSource[I + index] <> lpSubStr[index] then
break;
end;
if index < 1 then
begin
Result := I + 1;
Exit;
end
else if CharTable[Ord(lpSource[index + I])] = Char(Length(lpSubStr)) then
I := I + index - 1;
Inc(I);
end;
Result := -1
// 没有匹配的字符串
end;
{ TMainForm }
procedure TMainForm.Test(const AMsg: string);
var
nCount, nOffset,
I, nTick, nPos: Integer;
S1, S2: string;
Func: TPosEx;
begin
S1 := Edit1.Text;
S2 := Edit2.Text;
nCount := 1000000;
nOffset := 1;
nPos := -1;
with Memo1.Lines do
begin
Add(' - > ' + AMsg);
nTick := GetTickCount;
for I := 0 to nCount - 1 do
begin
nPos := FFunc(S1, S2, nOffset);
end;
nTick := GetTickCount - nTick;
Caption := IntToStr(nPos);
Add(' ' + IntToStr(nTick))
end;
end;
procedure TMainForm.Button1Click(Sender: TObject);
var
nCount, I, nPos: Integer;
S1, S2: string;
begin
Randomize;
nCount := RandomRange(8, 32);
SetLength(S1, nCount);
for I := 1 to nCount do S1 := Chr(RandomRange(Ord('a'), Ord('z')));
nCount := RandomRange(256, 1024);
SetLength(S2, nCount);
for I := 1 to nCount do S2 := Chr(RandomRange(Ord('a'), Ord('z')));
nPos := RandomRange(512, 1024)
{ 人为的构造查找结果 }
Insert(S1, S2, nPos);
Edit1.Text := S1;
Edit2.Text := S2;
Memo1.Lines.Clear;
end;
procedure TMainForm.Button2Click(Sender: TObject);
begin
FFunc := Delphi7PosEx;
Test('Delphi 7 PosEx');
FFunc := Delphi2007PosEx;
Test('Delphi 2007 PosEx');
FFunc := Q_PosStr;
Test('Q_PosStr');
FFunc := FindPosBM;
Test('FindPosBM');
FFunc := BMH;
Test('BMH');
FFunc := FastcodePosExSSE
{ 在我的机器上 FastcodeTarget -> 3 FastcodePosExSSE/FastcodePosExSSESizePenalty }
Test('FastCode');
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
Caption := IntToStr(Ord(FastcodeTarget));
end;
end.
AStartPos: Integer = 1): Integer;
const
MAX_CHAR = 256;
SizeInt = SizeOf(Integer);
type
PByteArr = ^TByteArr;
TByteArr = array[0..MaxInt - 1] of Byte;
var
Src, Sub: PByte;
I, J, CurrPos, SubLen, SrcLen: Integer;
Buffer: array[0..MAX_CHAR - 1] of Integer;
begin
Result := 0;
SubLen := Length(ASub);
SrcLen := Length(ASource);
if SubLen > SrcLen then
Exit;
Sub := PByte(ASub);
Src := PByte(ASource);
for I := 0 to MAX_CHAR - 1 do
Buffer := SubLen;
for I := 0 to SubLen - 2 do
Buffer[PByteArr(Sub)^] := SubLen - I - 1;
CurrPos := SubLen + AStartPos - 2;
while CurrPos < SrcLen do
begin
I := CurrPos;
J := SubLen - 1;
while (J >= 0) and ((PByteArr(Src)^ = PByteArr(Sub)^[J])) do
begin
Dec(J);
Dec(I);
end;
if - 1 = J then
begin
Result := CurrPos - SubLen + 1;
break;
end;
Inc(CurrPos, Buffer[PByteArr(Src)^[CurrPos]]);
end;
end;
function BMH(const lpSubStr, lpSource: string
StartPos: Integer = 1): Integer;
var
I, index, ExitLen: Integer;
CharTable: array[0..255] of Char;
begin
if Length(lpSubStr) < 1 then
begin
Result := -2
// 子字符串长度不能小于1位
Exit;
end;
// 初始化CharTable
FillChar(CharTable, sizeof(CharTable), Char(Length(lpSubStr)));
for I := Length(lpSubStr) downto 1 do
CharTable[Ord(lpSubStr)] := Char(Length(lpSubStr) - I);
if StartPos < 1 then
I := StartPos
else
I := StartPos - 1;
ExitLen := Length(lpSource) - Length(lpSubStr);
while I <= ExitLen do
begin
for index := Length(lpSubStr) downto 1 do
begin
if lpSource[I + index] <> lpSubStr[index] then
break;
end;
if index < 1 then
begin
Result := I + 1;
Exit;
end
else if CharTable[Ord(lpSource[index + I])] = Char(Length(lpSubStr)) then
I := I + index - 1;
Inc(I);
end;
Result := -1
// 没有匹配的字符串
end;
{ TMainForm }
procedure TMainForm.Test(const AMsg: string);
var
nCount, nOffset,
I, nTick, nPos: Integer;
S1, S2: string;
Func: TPosEx;
begin
S1 := Edit1.Text;
S2 := Edit2.Text;
nCount := 1000000;
nOffset := 1;
nPos := -1;
with Memo1.Lines do
begin
Add(' - > ' + AMsg);
nTick := GetTickCount;
for I := 0 to nCount - 1 do
begin
nPos := FFunc(S1, S2, nOffset);
end;
nTick := GetTickCount - nTick;
Caption := IntToStr(nPos);
Add(' ' + IntToStr(nTick))
end;
end;
procedure TMainForm.Button1Click(Sender: TObject);
var
nCount, I, nPos: Integer;
S1, S2: string;
begin
Randomize;
nCount := RandomRange(8, 32);
SetLength(S1, nCount);
for I := 1 to nCount do S1 := Chr(RandomRange(Ord('a'), Ord('z')));
nCount := RandomRange(256, 1024);
SetLength(S2, nCount);
for I := 1 to nCount do S2 := Chr(RandomRange(Ord('a'), Ord('z')));
nPos := RandomRange(512, 1024)
{ 人为的构造查找结果 }
Insert(S1, S2, nPos);
Edit1.Text := S1;
Edit2.Text := S2;
Memo1.Lines.Clear;
end;
procedure TMainForm.Button2Click(Sender: TObject);
begin
FFunc := Delphi7PosEx;
Test('Delphi 7 PosEx');
FFunc := Delphi2007PosEx;
Test('Delphi 2007 PosEx');
FFunc := Q_PosStr;
Test('Q_PosStr');
FFunc := FindPosBM;
Test('FindPosBM');
FFunc := BMH;
Test('BMH');
FFunc := FastcodePosExSSE
{ 在我的机器上 FastcodeTarget -> 3 FastcodePosExSSE/FastcodePosExSSESizePenalty }
Test('FastCode');
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
Caption := IntToStr(Ord(FastcodeTarget));
end;
end.