【发布时间】:2023-04-06 13:59:01
【问题描述】:
我必须检查我在 FileListBox 中是否有重复的路径(FileListBox 具有某种工作列表或播放列表的作用)。 使用 Delphi 的 SameText,CompareStr,CompareText,需要 6 秒。所以我带来了我自己的比较功能,它(只是)快一点但不够快。任何想法如何改进它?
function SameFile(CONST Path1, Path2: string): Boolean;
VAR i: Integer;
begin
Result:= Length(Path1)= Length(Path2); { if they have different lenghts then obviously are not the same file }
if Result then
for i:= Length(Path1) downto 1 DO { start from the end because it is more likely to find the difference there }
if Path1[i]<> Path2[i] then
begin
Result:= FALSE;
Break;
end;
end;
我是这样使用的:
for x:= JList.Count-1 downto 1 DO
begin
sMaster:= JList.Items[x];
for y:= x-1 downto 0 DO
if SameFile(sMaster, JList.Items[y]) then
begin
JList.Items.Delete (x); { REMOVE DUPLICATES }
Break;
end;
end;
注意:重复的可能性很小,因此不经常调用 Delete。此外,列表无法排序,因为项目是由用户添加的,有时顺序可能很重要。
更新:
问题是我失去了代码的优势,因为它是 Pascal。
如果比较循环( Path1[i] Path2[i] )可以优化为使用 Borland 的 ASM 代码,那就太好了。
Delphi 7,Win XP 32 位,测试完成了列表中的 577 个项目。从列表中删除项目不是问题,因为这种情况很少发生。
结论
正如 Svein Bringsli 所指出的,我的代码很慢不是因为比较算法,而是因为 TListBox。最佳解决方案由 Marcelo Cantos 提供。非常感谢马塞洛。
我接受了 Svein 的回答,因为它直接回答了我的问题“如何让我的比较函数更快”和“没有必要让它更快”。
目前我实现了肮脏和 快速实施 解决方案:当我的文件少于 200 个时,我使用我的慢代码来检查重复项。如果有超过 200 个文件,我会使用 dwrbudr 的解决方案(这该死的快),考虑到如果用户有这么多文件,那么顺序无论如何都无关紧要(人脑无法跟踪这么多项目)。
我要感谢大家的想法,特别是 Svein 揭露真相:(Borland 的)视觉控制太慢了!
【问题讨论】:
-
哈希表是最快的方法。然后,您有 O(n) 用于列表遍历和 O(1) 用于哈希搜索。所以你有 O(n) 复杂度。只需遍历列表并检查该项目是否已在哈希表中。
标签: delphi