贴点代码------字符串查找的不同方法与比较(0分)

  • 主题发起人 主题发起人 copy_paste
  • 开始时间 开始时间
C

copy_paste

Unregistered / Unconfirmed
GUEST, unregistred user!

//StringSearch.pas
object Form1: TForm1
Left = 192
Top = 107
Width = 506
Height = 372
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = '宋体'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 12
object SelectFileButton: TSpeedButton
Left = 168
Top = 48
Width = 23
Height = 22
Caption = '...'
OnClick = SelectFileButtonClick
end
object Label1: TLabel
Left = 24
Top = 24
Width = 114
Height = 12
Caption = '选择欲比较的文件(&S)'
FocusControl = FileEdit
end
object Label2: TLabel
Left = 208
Top = 24
Width = 126
Height = 12
Caption = '查找选择文件的字串(&F)'
FocusControl = FindEdit
end
object AddFileButton: TButton
Left = 24
Top = 80
Width = 113
Height = 25
Caption = '增加选中的文件'
TabOrder = 0
OnClick = AddFileButtonClick
end
object FileEdit: TEdit
Left = 24
Top = 48
Width = 145
Height = 20
TabOrder = 1
end
object MsgMemo: TMemo
Left = 0
Top = 128
Width = 498
Height = 217
Align = alBottom
ScrollBars = ssVertical
TabOrder = 2
end
object CompareButton: TButton
Left = 208
Top = 80
Width = 89
Height = 25
Caption = '开始比较'
TabOrder = 3
OnClick = CompareButtonClick
end
object FindEdit: TEdit
Left = 208
Top = 48
Width = 145
Height = 20
TabOrder = 4
end
object OpenDialog1: TOpenDialog
Left = 544
Top = 8
end
end
//StringSearch.pas
unit StringSearch;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, StrUtils;
type
TForm1 = class(TForm)
AddFileButton: TButton;
OpenDialog1: TOpenDialog;
FileEdit: TEdit;
SelectFileButton: TSpeedButton;
Label1: TLabel;
MsgMemo: TMemo;
CompareButton: TButton;
FindEdit: TEdit;
Label2: TLabel;
procedure AddFileButtonClick(Sender: TObject);
procedure SelectFileButtonClick(Sender: TObject);
procedure CompareButtonClick(Sender: TObject);
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
function FindPosWithBM(const ASource, ASub: string;
StartPos: Integer): 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 - 1do
Buffer := SubLen;
for I := 0 to SubLen - 2do
Buffer[PByteArr(Sub)^] := SubLen - I - 1;
CurrPos := SubLen + StartPos - 2;
while CurrPos < SrcLendo
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 FindPosWithKMP(const ASource, ASub: string;
StartPos: Integer): Integer;
const
MAX_STRLEN = 255;
var
Next: array [1..MAX_STRLEN] of Integer;
procedure InitNext;
var
I, J, Len: Integer;
begin
I := 1;
J := 0;
FillChar(Next, SizeOf(Next), 0);
Len := Length(ASub);
while I < Lendo
if (J = 0) or (ASub = ASub[J]) then
begin
Inc(I);
Inc(J);
Next := J;
end else
J := Next[J];
end;

var
I, J, SrcLen, SubLen: Integer;
begin
Result := 0;
InitNext;
I := StartPos;
J := 1;
SrcLen := Length(ASource);
SubLen := Length(ASub);
while (I <= SrcLen) and (J <= SubLen)do
begin
if (J = 0) or (ASource = ASub[J]) then
begin
Inc(I);
Inc(J);
end else
J := Next[J];
if J > SubLen then
begin
Result := I - SubLen;
break;
end;
end;
end;

procedure TForm1.AddFileButtonClick(Sender: TObject);
procedure AddFile(FileName: string);
const
TEST_SIZE = 10024 * 1000;
var
Buffer: Pointer;
FileSize, Count: Integer;
begin
with TFileStream.Create(FileName, fmOpenReadWrite)do
try
FileSize := Size;
Count := FileSize;
GetMem(Buffer, Count);
try
ReadBuffer(Buffer^, Count);
Inc(FileSize, Write(Buffer^, Count));
while TEST_SIZE > FileSizedo
Inc(FileSize, Write(Buffer^, Count));
Caption := Format('文件大小为:%d', [FileSize]);
finally
FreeMem(Buffer);
end;
finally
Free;
end;
end;

begin
AddFile(FileEdit.Text);
end;

procedure TForm1.SelectFileButtonClick(Sender: TObject);
begin
with OpenDialog1do
if Execute then
FileEdit.Text := FileName;
end;

{$IFNDEF VER150} { D7函数 }
function PosEx(const SubStr, S: string;
Offset: Cardinal = 1): Integer;
var
I,X: Integer;
Len, LenSubStr: Integer;
begin
if Offset = 1 then
Result := Pos(SubStr, S)
else
begin
I := Offset;
LenSubStr := Length(SubStr);
Len := Length(S) - LenSubStr + 1;
while I <= Lendo
begin
if S = SubStr[1] then
begin
X := 1;
while (X < LenSubStr) and (S[I + X] = SubStr[X + 1])do
Inc(X);
if (X = LenSubStr) then
begin
Result := I;
exit;
end;
end;
Inc(I);
end;
Result := 0;
end;
end;
{$ENDIF}
function FindPosWithSys(const ASource, ASub: string;
StartPos: Integer): Integer;
begin
Result := PosEx(ASub, ASource, StartPos);
end;

{
Q_PosStr函数说明
参数:FindString,要查找的字符串
SourceString,源字符串
StartPos,从什么位置开始查找(所以,你可以用这个参数来查找下一个匹配的字符串)
返回值:如果找到了,返回找到的位置,否则,返回0
}
function Q_PosStr(const FindString, SourceString: string;
StartPos: Integer): Integer;
asm
PUSH ESI
PUSH EDI
PUSH EBX
PUSH EDX
TEST EAX,EAX
JE @@qt
TEST EDX,EDX
JE @@qt0
MOV ESI,EAX
MOV EDI,EDX
MOV EAX,[EAX-4]
MOV EDX,[EDX-4]
DEC EAX
SUB EDX,EAX
DEC ECX
SUB EDX,ECX
JNG @@qt0
XCHG EAX,EDX
ADD EDI,ECX
MOV ECX,EAX
JMP @@nx
@@fr: INC EDI
DEC ECX
JE @@qt0
@@nx: MOV EBX,EDX
MOV AL,BYTE PTR [ESI]
@@lp1: CMP AL,BYTE PTR [EDI]
JE @@uu
INC EDI
DEC ECX
JE @@qt0
CMP AL,BYTE PTR [EDI]
JE @@uu
INC EDI
DEC ECX
JE @@qt0
CMP AL,BYTE PTR [EDI]
JE @@uu
INC EDI
DEC ECX
JE @@qt0
CMP AL,BYTE PTR [EDI]
JE @@uu
INC EDI
DEC ECX
JNE @@lp1
@@qt0: XOR EAX,EAX
@@qt: POP ECX
POP EBX
POP EDI
POP ESI
RET
@@uu: TEST EDX,EDX
JE @@fd
@@lp2: MOV AL,BYTE PTR [ESI+EBX]
CMP AL,BYTE PTR [EDI+EBX]
JNE @@fr
DEC EBX
JE @@fd
MOV AL,BYTE PTR [ESI+EBX]
CMP AL,BYTE PTR [EDI+EBX]
JNE @@fr
DEC EBX
JE @@fd
MOV AL,BYTE PTR [ESI+EBX]
CMP AL,BYTE PTR [EDI+EBX]
JNE @@fr
DEC EBX
JE @@fd
MOV AL,BYTE PTR [ESI+EBX]
CMP AL,BYTE PTR [EDI+EBX]
JNE @@fr
DEC EBX
JNE @@lp2
@@fd: LEA EAX,[EDI+1]
SUB EAX,[ESP]
POP ECX
POP EBX
POP EDI
POP ESI
end;

function FindPosWithQ_PosStr(const ASource, ASub: string;
AStartPos: Integer): Integer;
begin
Result := Q_PosStr(ASub, ASource, AStartPos);
end;

type
TFindPos = function(const ASource, ASub: string;
StartPos: Integer): Integer;
procedure TForm1.CompareButtonClick(Sender: TObject);
function StringFromFile(const FileName: string): string;
var
FileSize: Integer;
begin
with TMemoryStream.Createdo
try
LoadFromFile(FileName);
FileSize := Size;
SetLength(Result, FileSize);
Move(Memory^, Result[1], FileSize);
finally
Free;
end;
end;

procedure Search(const ASource, ASub, MethodName: string;
SearchPos: TFindPos);
var
S1, E1: DWORD;
S2, E2: Int64;
SubLen, StartPos, SearchCount: Integer;
begin
S1 := GetTickCount;
QueryPerformanceCounter(S2);
StartPos := 1;
SearchCount := 0;
SubLen := Length(ASub);
StartPos := SearchPos(ASource, ASub, StartPos);
while StartPos <> 0do
begin
Inc(SearchCount);
Inc(StartPos, SubLen);
StartPos := SearchPos(ASource, ASub, StartPos);
end;
QueryPerformanceCounter(E2);
E1 := GetTickCount;
MsgMemo.Lines.Add(Format('%20.20s GetTick Time: %10.10d, Query Counter: %10.10d, Search: %d',
[MethodName, E1 - S1, E2 - S2, SearchCount]));
end;

var
Source, Find: string;
begin
Find := Trim(FindEdit.Text);
if Find = '' then
raise Exception.Create('嗯,找到N多,俺就不说了。');
Source := StringFromFile(FileEdit.Text);
try
Search(Source, Find, 'FindPosWithSys', FindPosWithSys);
Search(Source, Find, 'FindPosWithBM', FindPosWithBM);
Search(Source, Find, 'FindPosWithKMP', FindPosWithKMP);
Search(Source, Find, 'FindPosWithQ_PosStr', FindPosWithQ_PosStr);
finally
SetLength(Source, 0);
end;
end;

end.
 
copy_paste:
烦请给我发一个MyReader 1.03的代码给我。谢谢。
besteagle73@sina.com
 
接受答案了.
 
后退
顶部