如何删除文本文件中的重复行?在线等。。(100分)

  • 主题发起人 主题发起人 lytianshi
  • 开始时间 开始时间
L

lytianshi

Unregistered / Unconfirmed
GUEST, unregistred user!

1111111
2222222
1111111
3333333

得到
1111111
2222222
3333333
 
procedure DeleteDuplicate(FileName:string);
var
I:Integer;
SrcStrings,DestStrings:TStringList;
begin
SrcStrings:=TStringList.Create;
DestStrings:=TStringList.Create;
SrcStrings.LoadFromFile(FileName);
for I:=0 to SrcStrings.Count-1 do
if DestStrings.IndexOf(SrcStrings)=-1 then
DestStrings.Add(SrcStrings);
DestStrings.SaveToFile(FileName);
SrcStrings.Free;
DestStrings.Free;
end;
 
速度较快的正解
 
水平有限,希望详细说一下
for I:=0 to SrcStrings.Count-1 do
if DestStrings.IndexOf(SrcStrings)=-1 then
DestStrings.Add(SrcStrings);
DestStrings.SaveToFile(FileName);
通过怎样的操作实现功能的
 
我来解释一下代码//
procedure DeleteDuplicate(FileName:string);
var
I:Integer;
SrcStrings,DestStrings:TStringList;
begin
SrcStrings:=TStringList.Create; //原始的数据通过LOADFROMFILE到TSTRINGLIST中。
DestStrings:=TStringList.Create; //另一个TSTRINGLIST,用于保存不重复的数据
SrcStrings.LoadFromFile(FileName);//原始的数据通过LOADFROMFILE到TSTRINGLIST中。

for I:=0 to SrcStrings.Count-1 do
if DestStrings.IndexOf(SrcStrings)=-1 then //如果目的TSTRINGLIST中没有这一行数据则加入 ,用于去掉重复的数据
DestStrings.Add(SrcStrings);
DestStrings.SaveToFile(FileName);//把不重复的数据保存为文件。
SrcStrings.Free; //释放TSTRINGLIST
DestStrings.Free; //释放TSTRINGLIST
end;
 
速度较慢的方法
TStringList
用Sort排序
当前行是否和前一行相等
。。。。。
 
鄙视下L猪。这么容易的代码都看不明白还想了解内部实现。内部实现也很简单看VCL Source就知道了。不过我知道不行的。不但没水平 更没道德。有了答案不结贴。
 
谢谢.休息了~
 
以前,给 任远兄 做了一个优化,现在贴出来。

词库大小 10 万条 分析的文本 144 KB

TStringList 单词数 5009 耗时 1241毫秒
TStringList 单词数 5009 耗时 1282毫秒
TStringList 单词数 5009 耗时 1202毫秒
TStringList 单词数 5009 耗时 1222毫秒
TStringList 单词数 5009 耗时 1192毫秒
TStringList 单词数 5009 耗时 1192毫秒

TmyStringList 单词数 5009 耗时 211毫秒
TmyStringList 单词数 5009 耗时 240毫秒
TmyStringList 单词数 5009 耗时 240毫秒
TmyStringList 单词数 5009 耗时 110毫秒
TmyStringList 单词数 5009 耗时 130毫秒
TmyStringList 单词数 5009 耗时 251毫秒
TmyStringList 单词数 5009 耗时 250毫秒
大约快 5倍 左右。

测试代码:

_Source2 := TmyStringList.Create;
_Source2.LoadFromFile(ExtractFilePath(Application.ExeName) + 'c.txt');
TmyStringList(_Source2).CaseSensitive := true;
TmyStringList(_Source2).Sorted := true;
{
_Source2 := TStringList.Create;
_Source2.LoadFromFile(ExtractFilePath(Application.ExeName) + 'c.txt');
TStringList(_Source2).CaseSensitive := true;
TStringList(_Source2).Sorted := true;
}

procedure TForm1.Button2Click(Sender: TObject);
var
c, i: integer;
s: string;
wordstr: string;
KeyFound: integer;
btime: Cardinal;
sl: TStringList;
begin
Label1.Caption := '';
s := Memo1.Text;
//////////////////////
sl := TStringList.Create;
btime := GetTickCount;
c := 0;
for i := 1 to length(s) - 3 do
begin
wordstr := copy(s, i, 4);
KeyFound := _Source2.IndexOf(wordstr);
if KeyFound >= 0 then
begin
sl.add(_Source2[KeyFound]);
inc(c);
end;
end;
Memo3.Lines.add(format('%s 单词数 %d 耗时 %d毫秒', [_Source2.ClassName, c, GetTickCount - btime]));
//////////////////////////
Memo2.Lines.Assign(sl);
FreeAndNil(sl);
end;

优化代码:

FTable: array[0..1024 * 16] of TidxRec; /////////////

procedure TmyStringList.SetSorted(Value: Boolean);
begin
if FSorted <> Value then
begin
if Value then Sort;
FSorted := Value;
if FSorted then
maketable;
end;
end;

function TmyStringList.Find(const S: string; var Index: Integer): Boolean;
var
L, H, I, C: Integer;
idx: Integer;
begin
Result := False;
{
L := 0;
H := FCount - 1;
}
idx := getstridx(@(s[1]), length(s));
with FTable[idx] do
begin
if beginIdx < 0 then
exit;
L := beginIdx;
H := endIdx;
end;
。。。。。。。。。
procedure TmyStringList.maketable;
var
l, i, idx: integer;
begin
for i := 0 to high(FTable) do
with FTable do
begin
beginIdx := -1;
endIdx := -1;
end;
for i := 0 to FCount - 1 do
begin
with FList do
begin
l := length(FString);
idx := getstridx(@(FString[1]), l);
end;
with FTable[idx] do
begin
if beginIdx < 0 then
begin
beginIdx := i;
endIdx := i;
end
else
endIdx := i;
end;
end;
end;
 
来自:地质灾害, 时间:2008-6-2 19:45:35, ID:3898455
鄙视下L猪。这么容易的代码都看不明白还想了解内部实现。内部实现也很简单看VCL Source就知道了。不过我知道不行的。不但没水平 更没道德。有了答案不结贴。

呵呵~因为你们的都太复杂了,不是最简单的解决方案.
 
最简单的方法用 THashedStringList 在inifile中,只要写如下代码:
HashedStringList:THashedStringList;
HashedStringList:=THashedStringList.create;
HashedStringList.Sorted:=True;
HashedStringList.Duplicates:=dupIgnore;
就可以。
 
后退
顶部