Две быстрые строковые функции
Тот, кому приходилось "переваривать" (по-другому не назвать) длинные строки с помощью StringReplace, тот знает, что с увеличением длины строки время работы функции растет почти экспоненциально. Лично у меня доходило до нескольких секунд.
И в интернете я тогда нашел такую функцию:
Код Delphi:function FastStringReplace(const S: ansistring; OldPattern: ansistring; const NewPattern: ansistring; Flags: TReplaceFlags = [rfReplaceAll]): ansistring; var I, J, Idx: Integer; IsEqual: Boolean; UpperFindStr: ansistring; pS: PChar; // Указатель на массив для сравнения символов CanReplace: Boolean; begin if OldPattern = '' then begin Result := S; Exit; end; Result := ''; if S = '' then Exit; if rfIgnoreCase in Flags then begin OldPattern := AnsiUpperCase(OldPattern); // Для режима "не учитывать регистр" // потребуется дополнительная строка UpperFindStr := AnsiUpperCase(S); pS := PChar(UpperFindStr); end else pS := PChar(S); // Если новая подстрока не превышает старой, то... if Length(OldPattern) >= Length(NewPattern) then begin SetLength(Result, Length(S)); end else // Точный размер буфера не известен... SetLength(Result, (Length(S) + Length(OldPattern) + Length(NewPattern)) * 2); I := 1; Idx := 0; CanReplace := True; while I <= Length(S) do begin IsEqual := False; if CanReplace then // Если замена разрешена begin // Если I-й символ совпадает с OldPattern[1] if pS[I - 1] = OldPattern[1] then // Запускаем цикл поиска begin IsEqual := True; for J := 2 to Length(OldPattern) do begin if pS[I + J - 2] <> OldPattern[J] then begin IsEqual := False; Break; // Прерываем внутренний цикл end; end; // Совпадение найдено! Выполняем замену if IsEqual then begin for J := 1 to Length(NewPattern) do begin Inc(Idx); // Расширяем строку Result при необходимости if Idx > Length(Result) then SetLength(Result, Length(Result) * 2); Result[Idx] := NewPattern[J]; end; // Пропускаем байты в исходной строке Inc(I, Length(OldPattern)); if not (rfReplaceAll in Flags) then CanReplace := False; // Запрещаем дальнейшую замену end; end; end; // Если подстрока не найдена, то просто копируем символ if not IsEqual then begin Inc(Idx); // Расширяем строку Result при необходимости if Idx > Length(Result) then SetLength(Result, Length(Result) * 2); Result[Idx] := S[I]; Inc(I); end; end; // while I <= Length(S) do // Ограничиваем длину строки-результата SetLength(Result, Idx); end;
А это - самописная функция для подсчета числа вхождений подстроки в строку. И использует она именно описанную выше FastStringReplace.
Код Delphi:function CountPos(const subtext: string; Text: string): Integer; begin if ((Length(subtext) = 0) or (Length(Text) = 0) or (Pos(subtext, Text) = 0)) then Result := 0 else Result := (Length(Text) - Length(FastStringReplace(Text, subtext, '', [rfReplaceAll]))) div Length(subtext); end;
Оставьте свой комментарий
Войдите, чтобы оставлять комментарии
Оставить комментарий как гость