同样的问题见帖子http://www.csdn.net/expert/topic/1043/1043077.xml?temp=.7008936
问题一
我想将一个很大的文本文件的内容经过一定的文本替换处理后读入一个字符型变量txtall中,并将经处理后的文本内容显示到RichEdit1中.我的代码如下:
RichEdit1.Lines.LoadFromFile(OpenDialog1.FileName);
RichEdit1.Text:=StringReplace(RichEdit1.Text,'-','',[rfReplaceAll]);//, rfIgnoreCase]);
txtall:=RichEdit1.Text;
我发现执行第一行代码用的时间很短,但是第二行代码执行时间非常长.
请问如何改进代码才能使用时最短.顺便说明,以上提到的文本文件的行数在10万行以上,文本中有大量的字符'-'要删除.问题二
Delphi中有没有替换某个字符串中从某个位置开始的长度为N的子串为另一字符串的函数?在VB中可以用Mid$函数,那么在DELPHI中用哪个函数呢?
Private Sub Command1_Click()
Dim str As String
str = "abcdefghijklm"
Mid$(str, 4, 5) = "XYZAB" ' 将str的第四个字符开始的5个字符defg替换为XYZAB
MsgBox str
End Sub我用VB的Replace函数载入一个1400多行的文本文件(含有大量的'-'号,大约占44%),并将其中的'-'替换为'',最后显示处理后的结果显示在RichEdit中只需要0.12秒,用我前面的Delphi代码竟然用了3.79妙!同样有大量的替换操作,为何VB快这么多?当处理5万多行的文本文件时,VB用时22秒,用Delphi算了五分钟都毫无反映?高手们,救命啊,我刚开始学Delphi,给我一点对DELPHI的信心吧!
问题一
我想将一个很大的文本文件的内容经过一定的文本替换处理后读入一个字符型变量txtall中,并将经处理后的文本内容显示到RichEdit1中.我的代码如下:
RichEdit1.Lines.LoadFromFile(OpenDialog1.FileName);
RichEdit1.Text:=StringReplace(RichEdit1.Text,'-','',[rfReplaceAll]);//, rfIgnoreCase]);
txtall:=RichEdit1.Text;
我发现执行第一行代码用的时间很短,但是第二行代码执行时间非常长.
请问如何改进代码才能使用时最短.顺便说明,以上提到的文本文件的行数在10万行以上,文本中有大量的字符'-'要删除.问题二
Delphi中有没有替换某个字符串中从某个位置开始的长度为N的子串为另一字符串的函数?在VB中可以用Mid$函数,那么在DELPHI中用哪个函数呢?
Private Sub Command1_Click()
Dim str As String
str = "abcdefghijklm"
Mid$(str, 4, 5) = "XYZAB" ' 将str的第四个字符开始的5个字符defg替换为XYZAB
MsgBox str
End Sub我用VB的Replace函数载入一个1400多行的文本文件(含有大量的'-'号,大约占44%),并将其中的'-'替换为'',最后显示处理后的结果显示在RichEdit中只需要0.12秒,用我前面的Delphi代码竟然用了3.79妙!同样有大量的替换操作,为何VB快这么多?当处理5万多行的文本文件时,VB用时22秒,用Delphi算了五分钟都毫无反映?高手们,救命啊,我刚开始学Delphi,给我一点对DELPHI的信心吧!
delete(str,4,5);
s:='XYZAB';
insert(str,s,4);
看我的代码!!!!!!!用好DELPHI吧,大部分比VB快(可能有不快的方面)。
我是把“-“ 替换为“@”了。
procedure TForm1.Button1Click(Sender: TObject);
var
s:string;
i:integer;
begin
memo1.Visible :=false;
memo2.Visible :=false;
memo1.Lines.LoadFromFile('d:\shonline.txt');
for i:=0 to memo1.Lines.Count do
begin
s:=StringReplace(Memo1.Lines.Strings[i] ,'-','@',[rfReplaceAll]);
Memo2.Lines.Add(s);
end;
memo1.Visible :=true;
memo2.Visible :=true;
end;
PBufferLink = ^TBufferLink;
TBufferLink = Record
Buffer:PChar;
BufSize:integer;
Prev:PBufferLink;
end;function BigReplace(Source:String;OldStr, NewStr:string;BufferSize:integer=64000):string;
Var
CurLink,PrevLink:PBufferLink;
CurBufPos:integer;
FoundPos:integer;
OldStrLen,NewStrLen:integer; procedure NewBuf;
begin
GetMem(CurLink,SizeOf(TBufferLink));
With CurLink^ do
begin
GetMem(Buffer,BufferSize+1);
BufSize := BufferSize;
Buffer[BufferSize]:=#0;
Prev := PrevLink;
PrevLink:=CurLink;
end;
end; procedure FillBuf(const s:string;Size:integer);
var
P:PChar;
begin
while true do
begin
if CurBufPos+Size>BufferSize then
begin
P:=CurLink^.Buffer+CurBufPos;
Move(PChar(S)^,P^,BufferSize - CurBufPos);
Dec(Size,BufferSize - CurBufPos);
CurBufPos:=0; NewBuf;
end else
begin
P:=CurLink^.Buffer+CurBufPos;
Move(PChar(S)^,P^,Size);
inc(CurBufPos,Size);
Break;
end;
end;
end;
begin
CurLink:=Nil;
PrevLink:=Nil;
CurBufPos:=0;
OldStrLen:=Length(OldStr);
NewStrLen:=Length(NewStr);
Try
NewBuf; While True do
begin
FoundPos:= Pos(OldStr,Source);
if FoundPos>0 then
begin
FillBuf(Source,FoundPos -1);
FillBuf(NewStr,NewStrLen);
Delete(Source,1,FoundPos + OldStrLen -1);
end else
begin
FillBuf(Source,Length(Source));
Break;
end;
end;
finally
if CurBufPos<BufferSize then CurLink.Buffer[CurBufPos]:=#0;
Result:='';
while CurLink<>Nil do
begin
Result:=Result + String(CurLink.Buffer);
FreeMem(CurLink^.Buffer);
PrevLink:=CurLink.Prev;
FreeMem(CurLink);
CurLink:=PrevLink;
end;
end;
end;
AnsiReplaceStr(const AText, AFromText, AToText: string): string;
AText为那个文本,AFromText为要查找的文本,AToText为要替换成的文本。唉!我太弱了。
收藏
你的函数我试了,好象没有DELPHI自己带的快。
最好多几次测试,取个平匀值。
我的文本共 80414 行,每一行都有“-”,我用我的笔记本(PIII800,128M)做的测试,用DLPHI自己的,共用时: 16.9秒,而你的函数用了:20.2秒。
(别生气,我没别的意思,只是技术讨论)我把程序源程序放在网上,大家可以试一下,包括测试文本。http://www.cnborn.com/str.zip (是DELPHI6下调试的)
欢迎下载测试一下。
PBufferLink = ^TBufferLink;
TBufferLink = Record
Buffer:PChar;
BufSize:integer;
Prev:PBufferLink;
end;function BigReplace(Source:String;OldStr, NewStr:string;BufferSize:integer=64000):string;
Var
CurLink,PrevLink:PBufferLink;
CurBufPos:integer;
FoundPos:integer;
OldStrLen,NewStrLen:integer;
POldStr,PNewStr,PSource:PChar; procedure NewBuf;
begin
GetMem(CurLink,SizeOf(TBufferLink));
With CurLink^ do
begin
GetMem(Buffer,BufferSize+1);
BufSize := BufferSize;
Buffer[BufferSize]:=#0;
Prev := PrevLink;
PrevLink:=CurLink;
end;
end; procedure FillBuf(s:pchar;Size:integer);
var
P:PChar;
begin
if Size<=0 then Exit;
while true do
begin
if CurBufPos+Size>BufferSize then
begin
P:=CurLink^.Buffer+CurBufPos;
Move(S^,P^,BufferSize - CurBufPos);
Dec(Size,BufferSize - CurBufPos);
S:=S+BufferSize - CurBufPos;
CurBufPos:=0; NewBuf;
end else
begin
P:=CurLink^.Buffer+CurBufPos;
Move(S^,P^,Size);
inc(CurBufPos,Size);
Break;
end;
end;
end; Function MyPos(Str,SubStr:PChar):integer;
var
I,L:integer;
begin
Result:=0;
I:=0;
L:=Length(SubStr);
While True do
begin
if Str[I]=#0 then Exit else
if SubStr[0]=Str[I] then
begin
if CompareString(LOCALE_USER_DEFAULT, 0, Str+I,L, SubStr, L) = 2 then
begin
Result:= I+1;
Exit;
end;
end;
Inc(I);
end;
end;begin
CurLink:=Nil;
PrevLink:=Nil;
CurBufPos:=0;
OldStrLen:=Length(OldStr);
NewStrLen:=Length(NewStr);
PSource:=PChar(Source);
POldStr:=PChar(OldStr);
PNewStr:=PChar(NewStr);
Try
NewBuf; While True do
begin
FoundPos:=myPos(PSource,POldStr);
if FoundPos>0 then
begin
FillBuf(PSource,FoundPos -1);
FillBuf(PNewStr,NewStrLen);
PSource:=PSource+FoundPos+OldStrLen-1;
end else
begin
FillBuf(PSource,Length(PSource));
Break;
end;
end;
finally
if CurBufPos<BufferSize then CurLink.Buffer[CurBufPos]:=#0;
Result:='';
while CurLink<>Nil do
begin
Result:=String(CurLink.Buffer) + Result;
FreeMem(CurLink^.Buffer);
PrevLink:=CurLink.Prev;
FreeMem(CurLink);
CurLink:=PrevLink;
end;
end;
end;
RichEdit1.Lines.LoadFromFile(OpenDialog1.FileName);
RichEdit1.Text:=bigReplace(RichEdit1.Text,'-','',length(RichEdit1.Text));
txtall:=RichEdit1.Text;