我知道如何使用排序的Tstringlist列表的dupignore从中删除重复的字符串。
CallData := TStringList.Create;
CallData.Sorted := True;
Call.Duplicates := dupIgnore;
,但在我的例子中,字符串不能被排序,。
当indexOF有数十万行时,使用FOR循环查找重复非常慢(也使用TStringList ())。
if OpenDialog1.Execute then
begin
Try
y := TStringList.create;
f := TStreamReader.create(OpenDialog1.FileName, TEncoding.UTF8, True);
while not f.EndOfStream do
begin
l := f.ReadLine;
X.Add(l);
end;
g := Tstreamwriter.create('d:\logX.txt', True, TEncoding.UTF8);
for I := 0 to X.count - 1 do
begin
if y.IndexOf(X[I]) = -1 then
y.Add(X[I]);
end;
for j := 0 to y.count - 1 do
g.WriteLine(y[j]);
Finally
f.free;
y.free;
g.free;
End;
end;
还有更好的办法吗?
发布于 2017-12-14 09:06:02
下面是我如何处理这个问题的方法:
如果要删除大量重复项,则重复从字符串列表中删除将影响上述操作的性能。这是因为要删除的每一项都会导致后面的项向下移动一个索引。您可以通过复制到新列表而不是删除内嵌来避免这种情况。
或者,您也可以这样操作:
Count
的变量初始化为零。Count
中,然后添加Count
。Count
元素。字典的重点是查找是一个O(1)操作,因此第二个算法具有O(n)的时间复杂度。
发布于 2017-12-14 12:06:56
我会用诡计,有一个排序和一个未排序的列表。如下所示:
y := TStringList.create;
s := TStringList.create;
s.Sorted := TRUE;
s.Duplicates := dupIgnore;
f := TStreamReader.create(OpenDialog1.FileName, TEncoding.UTF8, True);
while not f.EndOfStream do
begin
l := f.ReadLine;
s.Add(l);
if s.Count > y.Count then y.Add(l);
end;
// etc.
发布于 2017-12-14 14:04:17
function compareobjects
(list : Tstringlist;
index1 : integer;
index2 : integer
) : integer;
begin
if index1 = index2 then
result := 0
else
if integer(list.objects[index1]) < integer(list.objects[index2]) then
result := -1
else
result := 1;
end;
begin
Try
y := TStringList.create;
y.Sorted := true;
y.Duplicates := dupignore;
f := TStreamReader.create('c:\106x\q47780823.bat');
i := 0;
while not f.EndOfStream do
begin
inc(i);
line := f.readline;
y.Addobject(line,tobject(i));
end;
y.Sorted := false;
y.CustomSort(compareobjects);
for i := 0 to y.count - 1 do
WriteLn(y[i]);
Finally
f.free;
y.free;
End;
readln;
end.
我会跟踪行号(i
),并将其与字符串一起赋值,方法是将其转换为对象;对列表进行排序并一如既往地删除重复项,然后使用对象上的自定义排序对其进行取消排序。
https://stackoverflow.com/questions/47818390
复制相似问题