【问题标题】:The fastest way to compare a partial string?比较部分字符串的最快方法是什么?
【发布时间】:2009-08-15 14:32:24
【问题描述】:

我必须将部分字符串“SKILL___EU_______WAND_______CLERIC_______BASE_____01”与“SKILL”进行比较。这是为了检查前四个字符是否为“SKILL”。或仅第一个字符,此处需要优化

我的问题:

  1. 我不知道如何进行优化比较。
  2. 它必须重复 35 000 次,所以它必须是 非常 快。

谢谢!

【问题讨论】:

  • 前4个字符怎么可能是'SKILL'?!
  • 你是想转述我的问题吗?
  • 大声笑!不,我不是想解释你的问题。我只是指出这个字符串的前四个字符永远不会是'SKILL'。

标签: delphi string comparison delphi-2009


【解决方案1】:

使用 StrUtils.AnsiStartsStr 表示区分大小写,使用 StrUtils.AnsiStartsText 表示不区分大小写 (将 StrUtils 添加到您的 uses 子句中)

【讨论】:

    【解决方案2】:

    如今,35000 次重复确实不算多,你做什么都可能无关紧要。

    【讨论】:

    • 这是一个明智的想法。以最万无一失的方式进行操作,无论多慢,然后将结果存储起来,再也不做。
    • 这可能是明智的,它实际上并没有回答问题,无论问题是什么。所以我当然可以理解这被否决了。
    【解决方案3】:

    如果您真的想要最好的速度,您将不得不自己编写一个 StartsWith 函数。

    // untested, case-sensitive
    Function StartsWith(const find, text : string) : Boolean;
    var i, len : integer;
    begin
       result := true;
       len := Min(Length(find), Length(text));
       For i := 1 to len do
       Begin
         if (find[i] <> text[i]) 
         then begin
           result := False;
           break;
         end;
       End;   
    end;
    

    【讨论】:

    • Delphi 已经有了 AnsiStartsStr(区分大小写)/AnsiStartsText(不区分大小写)函数。没有必要重新实现它。只需使用“StrUtils”单元。
    • @Andreas,你说得对,我就是找不到。只希望完整的 Delphi 文档在线...我留下答案,它可能是自定义版本的入门。
    【解决方案4】:

    无论您选择哪种解决方案,请记住根据您当前的实施实际测试和基准测试

    否则你只是猜测,而不是优化。

    请注意premature optimization is the root of all evil

    祝你好运!

    【讨论】:

      【解决方案5】:

      我认为 Delphi 例程非常优化和快速,所以只需使用它们。

      var
        position : Integer;
      
      begin
        // AnsiPos
        //   returns the position of a substring in a string
        //   or 0 if the substring isn't found
        position := AnsiPos('SKILL', 'SKILL_______EU_______WAND_______CLERIC_______BASE_____01');
      end;
      

      【讨论】:

      • 这将继续扫描整个域字符串,即使第一个字符不相等。
      【解决方案6】:

      如果您只想检查第一个字符,您可以这样做:

      if 'S' = 'SKILL_______EU_______WAND_______CLERIC_______BASE_____01'[1] then
      begin
          showmessage('SKILL');
      end
      

      【讨论】:

      • 当然可以编译。不过,我没有在 Delphi 2009 中进行测试。我确信它会在所有 Delphi 版本上编译。
      • 我认为将括号运算符应用于字符串文字是不合法的。但如果你说它编译,我会相信你的话。请注意,Free Pascal 接受该语法(即使在“Delphi 模式”下)。
      【解决方案7】:

      我对 Delphi 了解不多,但我认为(在任何语言/框架/平台中)Regex 是字符串扫描的最快方式...

      您没有准确指定要搜索的所有条件...

      【讨论】:

      • 正则表达式非常完整,但它们的速度并不快。您应该将正则表达式用于复杂的搜索而​​不是微不足道的搜索,尤其是在速度至关重要的情况下。
      • “一点也不快”——你有那个链接吗?大多数正则表达式在 O(n) 内匹配,并且很难用手写代码击败。
      • @Henk Holterman:对不起,我应该更具体一些;在这个问题中的情况下快速。如果您只想检查字符串的前 4-5 个字符以查看其是否匹配,则最好使用专门为此设计和优化的函数。
      • 所以我才说他没有把所有条件都写清楚!
      【解决方案8】:

      为什么不这样做:

      function StartsWith( const AMatchStr, ATestStr : string ) : boolean;
      begin
        Result := SameText( AMatchStr, copy( ATestStr, 1, Length( AMatchStr ));
      end;
      

      这将不会处理 ATestStr 超出起始文本的任何部分。 布里

      【讨论】:

      • 但它会复制字符,不是绝对必要的。
      • 为什么不这样做呢?因为库已经自带了这样的功能,即使没有,也最好使用StrLComp而不是临时复制字符串。
      【解决方案9】:

      如果你只是检查前 4/5 个字符,你可以做什么

      i:= Length('SKILL');
      
      LeftStr('SKILL_______EU_______WAND_______CLERIC_______BASE_____01',i) = 'SKILL'
      

      【讨论】:

        【解决方案10】:
        if AnsiPos('SKILL', 'SKILL_______EU_______WAND_______CLERIC_______BASE_____01') > 0 then
        

        我认为这应该可以完成这项工作,我不知道 AnsiPos 的速度是快还是慢。每当我想比较字符串的片段时,它都对我有用。 AnsiPos() 返回一个整数值,表示您要查找的字符串的起始索引。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-03-15
          • 1970-01-01
          • 2013-11-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-09-03
          相关资源
          最近更新 更多