2016-10-07 16 views
2

以下の例のように、Pascalスクリプトで文字列が他の文字列に何回現れるかをカウントしたいとします。Pascal Script Count別の文字列に文字列が現れる回数

私はDelphi: count number of times a string occurs in another stringの答えを見ましたが、パスカルスクリプトにはPosExの機能はありません。私はHelloまたはWorldがここで発生した回数をカウントした場合、私は,(カンマ)は、ここで発生した回数をカウントした場合

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

、結果は4

をする必要があり、結果は3でなければなりません。

UPDATE

以下の機能が動作しますが、それはコピーの新しい変数に再び文字列を与えられた、と文字列の一部を削除それゆえ、それはゆっくりと働く。

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

あなたの実装は一般的に正しいです。

存在を除去するためにいくつかなされるべき最適化と無駄なコードは、次のとおり

  • repeat以内)if Pos(SubStr, S) <> 0ための第二試験は無意味です。それは常に本当です。 Sをテストしていますが、これはすでに関数startでテストされています。 DSStrは既にuntilでテストされています。
  • Pos(SubStr, DSStr)を複数回呼び出さない変数に保存する必要があります。
  • Length(Copy(DSStr, Pos(SubStr, DSStr), Length(SubStr)))は、実際にはLength(SubStr)と同じです。
  • SDSStrにコピーする必要はありません。 Sで直接作業することができます。これは値渡しのパラメータなので、関数の呼び出しに使用する変数は変更しないでください。
  • 最初のPos(SubStr, S) = 0のチェックをループの同じチェックで置き換えて、Posコールを1つ保存します。

あなたのコードの最適化されたバージョン:

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; 

しかし、実際には(Delphiはありません)Inno SetupのStringChange functionと、あなたが任意のアルゴリズムを自分でコーディングする必要はありません。

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ではなく、Pascalで実装されている可能性があります。StringChange

OccurrencesOfSubString('Hello World!, Hello World!, Hello World!, Hello World!', 'Hello') 
  • :11秒
  • あなたのコードのマイ最適化されたバージョン:49秒
  • あなたの元のコード:99秒
300万回の呼び出しでテスト

呼び出し回数が少なくても、すべての実装で十分です。

+0

ありがとう!私は十分な時間がなかったので、遅れて私の質問を自分の機能で更新しました。 :-( – GTAVLover

+0

優れたヘルプありがとうございました!私が 'S 'を使って直接作業すると、あなたの最適化されたバージョンの関数を呼び出した後に' S'の内容が失われないでしょうか? – GTAVLover

+0

パラメータを 'S:string'と宣言した場合、値は(コピーによって)渡されるので、関数の' S'への変更は文字列のコピーに対して行われ、使用される変数には影響しませんこの関数は定数文字列でも呼び出すことができることに注意してください - 'var S:string'で宣言されたパラメータとは反対です - これは参照渡しです' S '関数を呼び出すために使用されます - したがって、定数を変更することができないため、パラメータに定数文字列を使用することはできません。 –

関連する問題