web-dev-qa-db-ja.com

Delphi:文字列が別の文字列で発生する回数をカウントします

私はDelphi2007を使用していますが、ある文字列が別の文字列で発生する回数を数える簡単な方法があるかどうか疑問に思います。使用できる組み込み関数はありますか?

例:

  • 「How」は、「How areyou?」という文字列で1回発生します。
  • 「do」は、「How do youdo?」という文字列で2回出現します。
22
Jonas
function Occurrences(const Substring, Text: string): integer;
var
  offset: integer;
begin
  result := 0;
  offset := PosEx(Substring, Text, 1);
  while offset <> 0 do
  begin
    inc(result);
    offset := PosEx(Substring, Text, offset + length(Substring));
  end;
end;
38

これを行うために私が今まで見た中で最も賢い方法の1つ:

{ Returns a count of the number of occurences of SubText in Text }
function CountOccurences( const SubText: string;
                          const Text: string): Integer;
begin
  if (SubText = '') OR (Text = '') OR (Pos(SubText, Text) = 0) then
    Result := 0
  else
    Result := (Length(Text) - Length(StringReplace(Text, SubText, '', [rfReplaceAll]))) div  Length(subtext);
end;  { CountOccurences }
10
RobertFrank

large本文で頻繁にオカレンスを検索していて、パフォーマンスが問題になる場合は、 Boyer-Moore検索アルゴリズム)を試すことができます。

テキスト内のすべての出現を見つけるための最悪の場合、約3nの比較が必要です

Delphiでの実装は、私たち自身のSO here

高速検索、高速検索と置換、および文字列内の部分文字列の高速カウントという3つの高速文字列関数が必要です。

4

uses
  StrUtils;    

function Occurrences(const Substring, Text: string;
  const ignoreUppercase: Boolean = false): Integer;
var
  inSubstring, inText: string;
  inPos: Integer;
begin
  Result:= 0;

  if (Substring = '') or (Text = '') then
    Exit;

  if ignoreUppercase then
  begin
    inSubstring:= AnsiLowerCase(Substring);
    inText:=  AnsiLowerCase(Text);
  end
  else
  begin
    inSubstring:= Substring;
    inText:=  Text;
  end;

  inPos:= 1;

  repeat
    inPos:= posEx(inSubstring, inText, inPos);
    if inPos > 0 then
    begin
      Inc(Result);
      inPos:= inPos + Length(inSubstring);
    end;
  until inPos = 0;
end;

1
GoodMan
function stringcount(pBefore: String; pSubstring: String; pFlags: TReplaceFlags): Integer;
begin
  result:= round((pBefore.Length - stringreplace(pBefore, pSubstring, '', pFlags).Length) / pSubstring.Length);
end;
0
guest