Delphi: количество раз, которое строка встречается в другой строке - PullRequest
20 голосов
/ 10 марта 2011

Я использую Delphi 2007 и задаюсь вопросом, существует ли простой способ подсчета числа раз, когда строка встречается в другой строке. Любая встроенная функция, которую я могу использовать?

Примеры:

  • «Как» встречается один раз в строке «Как дела?»
  • "do" встречается дважды в строке "Как дела?"

Ответы [ 5 ]

37 голосов
/ 10 марта 2011
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;
9 голосов
/ 11 марта 2011

Один из самых умных способов, которые я когда-либо видел, чтобы сделать это:

{ 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 }
4 голосов
/ 11 марта 2011

Если вы обнаружите, что часто ищите в тексте большой текст и производительность становится проблемой, вы можете попробовать алгоритм Бойера-Мура .

наихудший случай, чтобы найти все вхождения в тексте нужно примерно 3н сравнение

Реализацию в Delphi можно найти на нашем собственном SO здесь

Мне нужно три строки быстро на больших функции: быстрый поиск, быстрый поиск и заменить, и быстрый подсчет подстроки в строке.

1 голос
/ 16 июля 2014

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;

0 голосов
/ 19 мая 2019
function stringcount(pBefore: String; pSubstring: String; pFlags: TReplaceFlags): Integer;
begin
  result:= round((pBefore.Length - stringreplace(pBefore, pSubstring, '', pFlags).Length) / pSubstring.Length);
end;
...