【问题标题】:Searching a sorted TStringList for an entry with a prefix (StartsText)在已排序的 TStringList 中搜索带有前缀的条目 (StartsText)
【发布时间】:2012-08-16 12:47:30
【问题描述】:

我有一个 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;

基本上,唯一真正的变化是它在移动到下一个要比较的条目之前进行检查。

请注意,不能从 TStringList 切换。

这种方法行得通吗?

谢谢

【问题讨论】:

  • “行得通吗?”你不能试一试就知道吗?该代码可能更简单,但如果您只想对您的代码进行评论,您可以转而访问 Stack Overflow 的“代码审查”站点。否则,我不确定您真正要求的是什么。
  • 我编写了一个测试例程来测试它,它似乎可以工作。我想我真的只是在问是否有任何明显的漏洞或更好/更快的方法(在将其保留为 TStringList 的限制下)。 Tnaks。
  • 效率重要吗?切换到二分搜索可能会在该领域快速获胜。
  • @Boileau,该代码已经进行了二分搜索。
  • 哎呀,我看错了代码!傻我。在这种情况下,我会投票赞成您的解决方案。

标签: delphi tstringlist


【解决方案1】:

如果TFilenameUtils.StartsFilenameStartsText 相同(并且您的第一段暗示它可能是),那么您可以通过使用 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;

这应该可行,因为当Find 失败时,它仍然会告诉您所需字符串 出现在列表中的位置的索引。当您搜索前缀字符串时,它的位置将位于以该前缀开头的任何其他字符串之前,因此如果有任何带有该前缀的字符串,它们将立即出现在前缀本身的假设位置之后。


如果您想保留当前代码,则可以通过删除检查C = 0 的条件来简化它。除非您的 StartsFilename 函数被破坏,否则这种情况永远不会发生。但是,如果函数确实被破坏并且C 可以 为零,那么您至少可以在此时停止执行循环,因为您已经找到了您要查找的内容。无论哪种方式,您都不需要检查 Duplicates,因为您的函数与 Find 的要求不同,可以返回找到的项目的索引。

【讨论】:

  • 我假设 .Size 实际上应该是 .Count ?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-11
  • 1970-01-01
  • 1970-01-01
  • 2020-08-18
  • 2015-08-13
  • 2018-05-06
  • 2014-01-22
相关资源
最近更新 更多