1 1 1 1 1 1 1 1 1 1 Рейтинг 0.00 (0 Голоса(ов)

Две быстрые строковые функции

Тот, кому приходилось "переваривать" (по-другому не назвать) длинные строки с помощью 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;

 

Оставьте свой комментарий

Оставить комментарий как гость

0
  • Комментариев нет