2016-10-07 11 views
2

Я хочу подсчитать, сколько раз строка возникает в другой строке в Pascal Script, как показано в приведенном ниже примере.Pascal Script Количество раз, когда строка встречается в другой строке

Я видел ответ Delphi: count number of times a string occurs in another string, но нет функции PosEx в Pascal Script.

MyString := 'Hello World!, Hello World!, Hello World!, Hello World!'; 

Если подсчитать количество раз Hello или World происходит здесь, результат должен быть 4.

Если подсчитать количество раз , (запятой) происходит здесь, результат должен быть 3.

UPDATE

следующая функция работает, но он копирует данную строку снова к новой переменной, и удаляет части строки s, поэтому он работает медленно.

function OccurrencesOfSubString(S, SubStr: String): Integer; 
var 
    DSStr: String; 
begin 
    if Pos(SubStr, S) = 0 then 
    Exit 
    else 
    DSStr := S; 
    Repeat 
    if Pos(SubStr, S) <> 0 then 
    Inc(Result); 
    Delete(DSStr, Pos(SubStr, DSStr), Length(Copy(DSStr, Pos(SubStr, DSStr), Length(SubStr)))); 
    Until Pos(SubStr, DSStr) = 0; 
end; 
+0

Это не служба написания кода. Вы приложили все усилия, чтобы сделать это самостоятельно? Вы можете сделать это без PosEx; это было сделано за десятилетия до того, как PosEx когда-либо существовал. –

+0

Да, но я не смог опубликовать свой код, потому что он не работает, как я ожидаю. – GTAVLover

+3

Затем отправьте свой код, который не работает, и * задайте конкретный вопрос * об этом коде. Опять же, это не служба написания кода, где вы публикуете свои требования и язык выбора, а кто-то издает код для вас. –

ответ

3

Ваша реализация в целом правильная.

Есть некоторые оптимизации, которые будут сделаны и бесполезно код должен быть удален:

  • Второе испытание для if Pos(SubStr, S) <> 0 (в пределах repeat) не имеет смысла. Это правда всегда. Вы тестируете S, который уже был протестирован при запуске функции. И DSStr уже протестирован в until.
  • Вы должны сохранить Pos(SubStr, DSStr) переменной, чтобы не называть ее несколько раз.
  • Length(Copy(DSStr, Pos(SubStr, DSStr), Length(SubStr))) на самом деле то же самое, что и Length(SubStr).
  • Не нужно копировать S в DSStr. Вы можете напрямую работать с S. Это параметр по-значению, поэтому вы не изменяете переменную, которую используете для вызова функции.
  • Замените начальную команду Pos(SubStr, S) = 0 с такой же проверкой в ​​цикле, чтобы сохранить один вызов Pos.

Оптимизированная версия кода:

function OccurrencesOfSubString(S, SubStr: String): Integer; 
var 
    P: Integer; 
begin 
    Result := 0; 
    repeat 
    P := Pos(SubStr, S); 
    if P > 0 then 
    begin 
     Inc(Result); 
     Delete(S, P, Length(SubStr)); 
    end; 
    until P = 0; 
end; 

Но на самом деле с Setup Inno StringChange function (что Delphi не имеет), вы не должны кодировать любой алгоритм самостоятельно.

function OccurrencesOfSubString(S, SubStr: String): Integer; 
begin 
    Result := StringChange(S, SubStr, ''); 
end; 

Это был вдохновлен @RobertFrank's answer to Delphi: count number of times a string occurs in another string.

В то время как использование StringChange выглядит неэффективным (так как оно имеет значительные побочные эффекты), оно на самом деле быстрее. Вероятно, потому, что он реализован в Паскале, а не в Pascal Script.

Испытано 3 миллиона вызовов:

OccurrencesOfSubString('Hello World!, Hello World!, Hello World!, Hello World!', 'Hello') 
  • С StringChange: 11 секунд
  • Моя оптимизированная версия кода: 49 секунд
  • Ваш исходный код: 99 секунд

Хотя для нескольких вызовов все реализации достаточно хороши.

+0

Спасибо! работает !, Поскольку у меня не было достаточно времени, я опоздал, чтобы обновить свой вопрос с помощью моей функции. :-( – GTAVLover

+0

Спасибо за отличную помощь! Если я работаю непосредственно с 'S', разве содержимое' S' не будет потеряно после вызова вашей оптимизированной версии моей функции? Что вы подразумевали под By-Value? – GTAVLover

+0

Если вы объявляете параметр как 'S: string', он передается по значению (путем копирования), поэтому любая модификация' S' в функции выполняется на копии строки и не влияет на используемую переменную Обратите внимание, что такой функцией могут быть и вызовы с постоянной строкой. - В отличие от параметра, объявленного как «var S: string» - это передается по ссылке. Любая модификация 'S' будет изменять переменную используется для вызова функции. И поэтому вы не можете использовать константу для параметра, так как константу нельзя изменить. –