Mic*_*ick 1 delphi tstringlist
我有一个TStringList,它被排序并包含唯一的文件名.该列表可以是任何大小(因此它可以是数十万个条目).我想检查是否有任何条目以特定字符串开头(即文件是否在子文件夹中).串行扫描列表并使用StartsText很容易,但这不是一个理想的解决方案.
使用TStringList.Find()代码作为起点,我创建了一个我认为是解决方案的函数,但我想确定.不要担心以下不是类的成员(FList是被搜索的TStringList实例),StartsFilename的工作方式与StartsText相同:
function ShortcutFind(const S: string): Boolean;
var
L, H, I, C: Integer;
begin
Result := False;
L := 0;
H := FList.Count - 1;
while L <= H do begin
I := (L + H) shr 1;
if TFilenameUtils.StartsFilename(FList[I], aFolder) then begin
Result:=TRUE;
Exit;
end;
C := FList.CompareStrings(FList[I], S);
if C < 0 then
L := I + 1
else begin
H := I - 1;
if C = 0 then begin
Result := True;
if FList.Duplicates <> dupAccept then L := I;
end;
end;
end;
end;
Run Code Online (Sandbox Code Playgroud)
基本上,唯一真正的变化是它在进入下一个要比较的条目之前进行检查.
请注意,从TStringList切换不是一个选项.
这种方法有用吗?
谢谢
如果TFilenameUtils.StartsFilename是StartsText(和你的第一段暗示它可能是)相同,那么你可以通过使用 TStringList.Find而不是复制它来在一个语句中完成整个函数:
var
I: Integer;
begin
Assert(not FList.CaseSensitive);
Result := FList.Find(S, I) or ((I < FList.Count) and StartsText(S, FList[I]));
end;
Run Code Online (Sandbox Code Playgroud)
这应该工作,因为当Find发生故障时,它仍然会告诉你在哪里所需字符串的索引就会出现在列表中.当您搜索前缀字符串时,其位置将位于以该前缀开头的任何其他字符串之前,因此如果有任何带有该前缀的字符串,它们将立即出现在前缀本身的假设位置之后.
如果要保留当前代码,则可以通过删除检查的条件来简化它C = 0.除非你的StartsFilename功能被破坏,否则不应该发生这种情况.但是,如果函数真的被打破并且C 可以为零,那么你至少可以在那个时候停止执行循环,因为你找到了你想要的东西.无论哪种方式,您都不需要检查,Duplicates因为您的函数Find与返回找到的项的索引的要求不同.
| 归档时间: |
|
| 查看次数: |
857 次 |
| 最近记录: |